Saltar al contenido

Instalar y configurar Tagr

Todo lo necesario para ejecutar Tagr, el editor de metadatos de música self hosted, en tu propio servidor. Docker Compose es el camino más rápido. Debajo tienes la instalación manual con Node.

Requisitos

Docker y el plugin de Docker Compose, en cualquier equipo que ejecute linux/amd64 o linux/arm64. Eso cubre la mayoría de NAS, un servidor doméstico, un VPS y una Raspberry Pi 4 o 5 con un sistema de 64 bits. Si prefieres no usar Docker, necesitas Node.js 22 o superior y pnpm. También necesitas permisos de lectura y escritura sobre las carpetas de música que quieras editar, porque Tagr escribe las etiquetas dentro de los propios archivos.

Inicio rápido con Docker Compose

Descarga el fichero compose del repositorio:

bash
wget https://raw.githubusercontent.com/suitux/Tagr/main/docker-compose.yml

Genera un secreto para firmar las sesiones y pega el resultado en AUTH_SECRET:

bash
openssl rand -hex 32

Edita el bloque de entorno, pon tu propio AUTH_USER y AUTH_PASSWORD, y apunta el segundo volumen a tu música. Después levántalo:

docker-compose.yml
services:
  tagr:
    image: ghcr.io/suitux/tagr:latest
    container_name: tagr
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - PUID=1000
      - PGID=1000
      - NODE_ENV=production
      - DATABASE_URL=file:/data/tagr.db
      - AUTH_SECRET=paste-your-generated-secret-here
      - AUTH_USER=admin
      - AUTH_PASSWORD=your-password-here
      - AUTH_URL=https://your-domain.com
    volumes:
      - sqlite_data:/data
      - /path/to/your/music:/music

volumes:
  sqlite_data:
bash
docker compose up -d

Abre http://localhost:3000, inicia sesión con las credenciales que hayas puesto y pulsa el botón de escanear para indexar la biblioteca. El primer escaneo lee cada archivo una vez, así que en una biblioteca grande tarda un rato.

Montar las carpetas de música

Tagr escanea /music de forma recursiva. Si tu música está repartida en varios sitios del anfitrión, monta cada uno como un subdirectorio dentro de /music y se recogen todos de forma automática:

docker-compose.yml
volumes:
  - /home/user/Music:/music/library
  - /mnt/nas/Music:/music/nas

MUSIC_FOLDERS solo hace falta cuando quieres restringir el escaneo a subdirectorios concretos, por ejemplo indexar /music/library y saltarte /music/podcasts. Si lo dejas sin definir, se escanea todo lo que cuelgue de /music.

Tagr necesita permiso de escritura sobre esas rutas. Pon PUID y PGID al usuario y al grupo que son dueños de los archivos en el anfitrión, o guardar una etiqueta fallará con un error de permisos.

Variables de entorno

Variable Obligatoria Descripción Ejemplo
DATABASE_URL Sí Ruta de la base de datos SQLite. Mantenla en un volumen persistente. file:/data/tagr.db
AUTH_SECRET Sí Secreto con el que se firman las sesiones JWT. Genéralo con openssl rand -hex 32. c5398a60cfd6...
AUTH_USER Sí Nombre de usuario de la cuenta inicial. admin
AUTH_PASSWORD Sí Contraseña de la cuenta inicial. una-contrasena-larga
AUTH_URL No URL pública de la instancia. Hace falta cuando Tagr está detrás de un proxy inverso, para que las redirecciones y las cookies de sesión apunten al origen correcto. https://tagr.ejemplo.com
MUSIC_FOLDERS No Lista de rutas a escanear, separadas por comas. Por defecto, /music. Ponlo solo para restringir el escaneo a subdirectorios concretos. /music/library,/music/nas
PUID No ID de usuario con el que corre el proceso del contenedor. Que coincida con el dueño de tus archivos. Solo en Docker. 1000
PGID No ID de grupo con el que corre el proceso del contenedor. Solo en Docker. 1000
NODE_ENV No Modo de ejecución. Usa production en un despliegue normal. production

Instalación manual

Necesita Node.js 22 o superior.

Crea un fichero .env en la raíz del proyecto:

.env
DATABASE_URL=file:./data/tagr.db
AUTH_SECRET="c5398a60cfd61607192d74ae8db237aaeaa07a98cd8ecdb8776c86eb87376ba3"
AUTH_USER="admin"
AUTH_PASSWORD="admin"
MUSIC_FOLDERS="/Users/youruser/Music,/Volumes/External/Music"

Después compila y arranca:

bash
git clone https://github.com/suitux/Tagr.git
cd Tagr
pnpm install
pnpm build && pnpm start

Escanear la biblioteca

Un escaneo recorre las carpetas configuradas, lee las etiquetas de cada archivo de audio con music-metadata e inserta o actualiza una fila por pista en SQLite. No se copia nada, no se mueve nada y no se recodifica ningún audio. La base de datos es un índice de tus archivos, no un sustituto.

Reescanear es seguro y se puede repetir. Los archivos nuevos se añaden, los que han desaparecido del disco se quitan del índice, y las filas existentes se actualizan en su sitio, así que tu historial de cambios sobrevive. Al terminar, un diálogo resume cuántos archivos se añadieron, se actualizaron y se eliminaron.

Desde el menú contextual del árbol de carpetas puedes reindexar una sola carpeta en vez de la biblioteca entera.

Actualizar

Descarga la nueva imagen y recrea el contenedor. El volumen de la base de datos no se toca, así que no se reescanea nada:

bash
docker compose pull && docker compose up -d

Copias de seguridad

Hay dos cosas que conviene respaldar, y solo una es de Tagr. Tus etiquetas viven dentro de los propios archivos de audio, así que tu copia de seguridad de la música ya las cubre. Lo que es de Tagr es la base de datos SQLite del volumen sqlite_data, que guarda el índice, tus filtros guardados, tus listas y el historial completo de cambios.

Copia la base de datos fuera del volumen con el contenedor parado, o haz una instantánea del volumen:

bash
docker compose stop tagr
docker run --rm -v sqlite_data:/data -v "$PWD":/backup alpine \
  tar czf /backup/tagr-db-backup.tar.gz -C /data .
docker compose start tagr

Problemas comunes

Guardar una etiqueta falla con un error de permisos

El proceso del contenedor no puede escribir en el archivo. Mira quién es el dueño de la música en el anfitrión con ls -ln, pon PUID y PGID a ese usuario y grupo, y recrea el contenedor. Un bind mount de solo lectura da el mismo síntoma, así que comprueba que el volumen no lleve :ro.

El escaneo termina pero no aparece ningún archivo

Lo más probable es que la música no esté bajo /music dentro del contenedor. Entra y míralo: docker exec -it tagr ls /music. Si la carpeta está vacía, la parte izquierda de los dos puntos del volumen apunta a una ruta equivocada del anfitrión. Si has puesto MUSIC_FOLDERS, confirma que sus rutas son rutas del contenedor, no del anfitrión.

El login redirige al host equivocado detrás de un proxy inverso

Pon AUTH_URL con la URL pública por la que navegas de verdad, incluido el esquema, por ejemplo https://tagr.ejemplo.com. Después asegúrate de que el proxy reenvía las cabeceras Host, X-Forwarded-Proto y X-Forwarded-For.

Notas sobre arm64 y Raspberry Pi

La imagen cubre linux/arm64, así que una Pi 4 o una Pi 5 valen, pero tienen que ir con un sistema de 64 bits. Con una Raspberry Pi OS de 32 bits no se puede descargar la imagen. En una Pi, cuenta con que el primer escaneo de una biblioteca grande sea lento, porque el límite está en leer cada archivo de la tarjeta SD o del disco USB.

Ejemplos de proxy inverso

Caddy, que se encarga del TLS por ti:

Caddyfile
tagr.example.com {
  reverse_proxy localhost:3000
}

Nginx:

nginx
server {
  listen 443 ssl;
  server_name tagr.example.com;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

En los dos casos, pon AUTH_URL con la URL pública para que las redirecciones de sesión acaben en el origen correcto.