En este tutorial veremos cómo instalar Loops, una plataforma de vídeos cortos muy similar a TikTok, pero con una gran diferencia: está basada en ActivityPub, lo que le permite integrarse de forma nativa en el Fediverso.
Gracias a este enfoque descentralizado, los vídeos que publiques en tu instancia de Loops podrán ser vistos, compartidos e interactuados desde otras plataformas compatibles como Mastodon, Pleroma, Misskey y muchas más.
A lo largo de la guía te explicaré los requisitos previos, los pasos de instalación y la configuración básica para dejar tu propia instancia de Loops lista y funcionando.
Ten en cuenta que Loops todavía está en fase alpha, por lo que pueden existir errores o limitaciones. Para más información actualizada y soporte, puedes visitar su repositorio oficial en GitHub.
Requisitos para Loops
En este tutorial trabajaremos sobre un servidor con Ubuntu 24.04, con acceso a usuario root. A lo largo del proceso instalaremos el siguiente software:
Instalación de LAMP o LEMP
Lo primero es contar con un servidor LAMP o LEMP completamente configurado. Eso sí, ten en cuenta que no es necesario instalar MariaDB, ya que en el caso de Loops utilizaremos MySQL.


Para la instalación de PHP, además tenemos que instalar todas estas librerías que son necesarias para Loops:
apt install php8.3-tokenizer php-json php8.3-pdo php8.3-fileinfo php8.3-bcmath php8.3-mbstring php8.3-ctype php8.3-xml php8.3-gd php8.3-redisInstalación de MySQL
Para la instalación de MySQL, seguiremos este otro tutorial que explica todo lo necesario:

Aprovecharemos para crear también la base de datos y guardar los datos de acceso para configurar más tarde:
CREATE DATABASE loops CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'loops_user'@'localhost' IDENTIFIED BY 'ContraseñaSegura';
GRANT ALL PRIVILEGES ON loops.* TO 'loops_user'@'localhost';
FLUSH PRIVILEGES;vRecuerda configurar un nombre de usuario y una base de datos distintos a los que se muestran en este ejemplo. Además, asegúrate de establecer una contraseña fuerte y segura.
Instalación de Redis Server
Para instalar redis-server en el servidor simplemente tienes que ejecutar este comando para su instalación:
apt install redis-serverInstalación de FFmpeg
Para adaptar los videos a la plataforma de Loops, también es necesario instalar el paquete ffmpeg en el servidor:
apt install ffmpegInstalación de NodeJS
También será necesario instalar NodeJS, para ello seguiremos también este tutorial. En este caso recomendamos instalar la versión 22 de NodeJS.

Instalación de Composer
Finalmente para instalar la aplicación, usaremos Composer, para ello lo instalaremos siguiendo este otro tutorial:

Instalación de Loops
Ahora sí, una vez instalado todo lo necesario, podemos comenzar con la instalación de Loops. El primer paso será descargar el repositorio en el directorio correspondiente:
cd /var/www/
git clone https://github.com/joinloops/loops-server.git
mv loops-server loopsEntramos dentro del directorio para instalar las dependencias de PHP:
cd /var/www/loops
composer install --no-dev --optimize-autoloaderEl siguiente paso es instalar las dependencias de NodeJS:
npm install
npm run buildCopiamos el fichero de ejemplo de configuración:
cp .env.example .envGeneramos la llave de aplicación:
php artisan key:generateEste comando automáticamente incluye la key en el fichero .env. Luego también añadimos el almacenamiento:
php artisan storage:linkLuego tendremos que editar el fichero .env y modificar todo a nuestras necesidades, a continuación os dejo algunos parámetros que se deben de configurar:
# De local a production
APP_ENV=production
# De true a false
APP_DEBUG=false
# Cambiamos localhost por el dominio
APP_URL=example.com
# Configuración de la base de datos
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=loops
DB_USERNAME=loops_user
DB_PASSWORD=ContraseñaSegura
# Configuración de Redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_DB=0
# Cache & Sessions
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
# Configuración del correo SMTP
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
# Añadimos también esto para el Video Processing
FFMPEG_BINARIES=/usr/bin/ffmpeg
FFPROBE_BINARIES=/usr/bin/ffprobeTras crear la configuración, podemos conectar la base de datos y lanzar las migraciones de la base de datos:
php artisan migrateSalida del comando
INFO Preparing database.
Creating migration table ............................................................................................................ 48.65ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table ............................................................................................... 274.56ms DONE
0001_01_01_000001_create_cache_table ................................................................................................ 65.87ms DONE
0001_01_01_000002_create_jobs_table ................................................................................................ 149.15ms DONE
2024_03_22_062441_create_profiles_table ............................................................................................ 143.04ms DONE
2024_03_23_232030_create_videos_table .............................................................................................. 420.49ms DONE
2024_03_28_105059_create_comments_table ............................................................................................ 243.75ms DONE
2024_03_30_060438_create_comment_replies_table ..................................................................................... 396.65ms DONE
2024_04_08_082610_create_followers_table ........................................................................................... 373.74ms DONE
2024_04_25_075914_create_notifications_table ....................................................................................... 550.37ms DONE
2024_04_25_081009_create_video_likes_table ......................................................................................... 272.40ms DONE
2024_04_25_081015_create_comment_likes_table ....................................................................................... 358.22ms DONE
2024_04_25_081348_create_comment_reply_likes_table ................................................................................. 373.28ms DONE
2024_04_27_053050_add_push_token_to_users_table .................................................................................... 389.07ms DONE
2024_08_29_090033_create_user_legacy_passwords_table ................................................................................ 71.81ms DONE
2024_08_29_100452_create_sounds_table .............................................................................................. 161.33ms DONE
2024_08_29_100554_create_reports_table ............................................................................................. 681.29ms DONE
2024_08_29_100601_create_user_filters_table ........................................................................................ 452.44ms DONE
2024_08_29_100623_create_topics_table .............................................................................................. 169.13ms DONE
2024_08_29_100642_create_video_topics_table ........................................................................................ 135.21ms DONE
2024_08_29_100832_create_user_cursors_table ......................................................................................... 83.52ms DONE
2025_02_09_082255_create_hashtags_table ............................................................................................ 146.08ms DONE
2025_02_09_082309_create_video_hashtags_table ...................................................................................... 344.00ms DONE
2025_06_22_103001_create_personal_access_tokens_table .............................................................................. 123.56ms DONE
2025_06_25_225818_create_admin_settings_table ...................................................................................... 200.98ms DONE
2025_07_06_042758_create_email_changes_table ....................................................................................... 440.20ms DONE
2025_07_06_064705_create_user_audit_logs_table ..................................................................................... 307.83ms DONE
2025_07_07_232033_create_data_exports_table ........................................................................................ 322.67ms DONE
2025_07_07_233800_create_user_data_settings_table .................................................................................. 208.78ms DONE
2025_07_08_041457_create_user_video_views_table .................................................................................... 281.04ms DONE
2025_07_12_073351_add_soft_deletes_to_comments_tables .............................................................................. 379.56ms DONE
2025_07_14_061311_add_reported_reply_id_to_reports_table ........................................................................... 586.42ms DONE
2025_07_18_051643_create_pages_table ............................................................................................... 188.56ms DONE
2025_07_21_082913_create_user_register_verifies_table .............................................................................. 150.89ms DONE
Por defecto el registro de Loops se encuentra desactivado, por ello es necesario registrar manualmente un usuario administrador:
php artisan create-admin-account
Configuración de las colas
Para que Loops funcione correctamente es necesario configurar las colas con Horizon. La forma más recomendable de gestionarlo es mediante Supervisor, que se encargará de ejecutar esta tarea de manera automática.
apt install supervidorY en la configuración añadimos lo siguiente:
nano /etc/supervisor/conf.d/loops-horizon.conf[program:loops-horizon]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/loops/artisan horizon
autostart=true
autorestart=true
user=www
redirect_stderr=true
stdout_logfile=/var/www/loops/storage/logs/horizon.log
stopwaitsecs=3600Guardamos el fichero de configuración para supervisor y modificamos los permisos del storage:
chown -R www:www /var/www/loops/storageReleemos la configuración y configuramos la configuración de supervisor.
supervisorctl reread
supervisorctl updateConfiguración del servidor web
Tanto si has decidido tirar por Nginx o por Apache, te dejo a continuación la configuración necesaria con lo que hay que cambiar:
Para Nginx:
En este bloque de código es necesario modificar server_name por el dominio y revisar que root sea la ruta correcta y que el PHP-FPM configurado en fastcgi_pass sea el instalado en el servidor.
server {
listen 80;
listen [::]:80;
server_name your-domain.com;
root /var/www/loops/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
# Handle large video uploads
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
}Para Apache
En este bloque de Apache, es necesario modificar ServerName por el nombre de tu dominio y revisar que tanto DocumentRoot y Directory sean las rutas correctas de la aplicación.
<VirtualHost *:80>
ServerName your-domain.com
DocumentRoot /var/www/loops/public
<Directory /var/www/loops/public>
AllowOverride All
Require all granted
</Directory>
# Handle large video uploads
LimitRequestBody 104857600
ErrorLog ${APACHE_LOG_DIR}/loops_error.log
CustomLog ${APACHE_LOG_DIR}/loops_access.log combined
</VirtualHost>Finalmente, revisamos que los permisos sean los correctos:
chown -R www-data:www-data /var/www/loops
chmod -R 755 /var/www/loops
chmod -R 775 /var/www/loops/storage
chmod -R 775 /var/www/loops/bootstrap/cacheConfiguramos crontab
Para que funcione todo correctamente y se lancen las tareas programadas, es necesario configurar este Cronjob:
crontab -eY añadimos al final lo siguiente:
* * * * * cd /var/www/loops && php artisan schedule:run >> /dev/null 2>&1Iniciar Loops en el servidor
Una vez realizada toda la configuración, es necesario reiniciar los servicios para que los cambios se apliquen. Podemos hacerlo de la siguiente manera:
php artisan horizon:terminateCon esto ya podremos acceder, desde nuestro navegador favorito, al dominio configurado y comprobar que Loops se carga correctamente.

Y podremos iniciar sesión con el administrador que hemos creado durante el proceso:

Si detectas algún problema, puedes reportarlo directamente en el apartado de Issues del repositorio en GitHub.
Para más información y detalles actualizados, consulta la documentación oficial disponible en el README del proyecto.
Más sobre ./voidNull
- 📖 Aprende todos sobre los comandos de GNU/Linux en nuestro Diccionario "De la A a la Z: Los comandos de GNU/Linux"
- 💪 ¡Forma parte de la Comunidad de ./voidNull!
- 🤖 Disfruta de todos nuestros Cursos sobre Ansible, Proxmox, Home Assistant entre otros.
- 📩 Mantente actualizado con lo último en GNU/Linux y Software Libre. Recibe nuestra Newsletter mensual.





Comentarios