◆ Guía Completa — Marzo 2026

Tu Propio
Spotify Local
en Proxmox

Servidor de streaming musical autoalojado con descarga automática de las listas más escuchadas de EE.UU., España, México y más. Sin suscripciones, sin rastreo, 100% tuyo.

Navidrome Proxmox VE spotDL Docker
Sección 01

Introducción y Arquitectura

Esta guía cubre la instalación completa de un servidor de música tipo Spotify, autoalojado en Proxmox. Combinaremos dos herramientas potentes:

Navidrome — Servidor de streaming musical open source, ligero y compatible con el protocolo Subsonic. Interfaz web moderna con soporte para múltiples usuarios, playlists, favoritos, letras y transcodificación al vuelo.

spotDL — Herramienta CLI que busca canciones en YouTube a partir de metadatos de Spotify. Descarga con carátulas, letras y metadatos completos. Su función sync permite mantener playlists actualizadas automáticamente.

Arquitectura del Sistema

🖥 Proxmox VE
Host de virtualización
🐳 Contenedor LXC
Debian 12 + Docker
⬇ spotDL + Cron
Descarga automática
💾 /music
Volumen compartido
📱 Symfonium
📱 play:Sub
🖥 Navegador Web
💻 Feishin
Sección 02

Requisitos Previos

Hardware

Navidrome es extremadamente ligero. Puede correr hasta en un Raspberry Pi.

ComponenteMínimoRecomendado
CPU1 core2 cores
RAM512 MB1-2 GB
Disco (SO)8 GB20 GB
Disco (música)Según colección500 GB+ (HDD/NAS)

Software

Proxmox VE 7.x o superior instalado y funcionando, acceso SSH al host, y conexión a internet en el contenedor para descargar música.

Sección 03

Creación del Contenedor LXC en Proxmox

Opción A: Interfaz Web

Abre la interfaz web de Proxmox en https://tu-ip:8006

Descarga el template de Debian 12 o Ubuntu 24.04 desde el repositorio

Crea un nuevo contenedor CT con los parámetros de la tabla

ParámetroValor
Hostnamenavidrome
Templatedebian-12-standard o ubuntu-24.04
Disco raíz16 GB
CPU2 cores
Memoria1024 MB
Swap512 MB
RedDHCP o IP estática
Nesting✅ Habilitado (necesario para Docker)

Opción B: Línea de Comandos SSH

bash
# Descargar template (si no lo tienes)
pveam download local debian-12-standard_12.7-1_amd64.tar.zst

# Crear contenedor
pct create 200 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
  --hostname navidrome \
  --memory 1024 --swap 512 \
  --cores 2 \
  --rootfs local-lvm:16 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --features nesting=1 \
  --unprivileged 1 \
  --start 1
💡 Consejo: IP Estática

Es muy recomendable asignar una IP estática para acceder siempre a Navidrome en la misma dirección. Usa: --net0 name=eth0,bridge=vmbr0,ip=192.168.1.50/24,gw=192.168.1.1

Montar almacenamiento externo (NAS/disco)

config
# Editar /etc/pve/lxc/200.conf en el host Proxmox
# Agregar línea para montar directorio:
mp0: /mnt/nas/music,mp=/mnt/music
Sección 04

Instalación de Docker y Docker Compose

Entra al contenedor y ejecuta los siguientes comandos para instalar Docker desde el repositorio oficial:

bash
# Entrar al contenedor desde Proxmox
pct enter 200

# Actualizar paquetes
apt update && apt upgrade -y

# Instalar dependencias
apt install -y ca-certificates curl gnupg lsb-release

# Agregar repositorio oficial de Docker
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
  | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" \
  | tee /etc/apt/sources.list.d/docker.list > /dev/null

# Instalar Docker
apt update
apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

# Verificar instalación
docker --version
docker compose version
ℹ️ Para Ubuntu

Si usas Ubuntu en lugar de Debian, cambia debian por ubuntu en la URL del repositorio de Docker.

Sección 06

Configuración de Navidrome

Primer acceso

Abre tu navegador → http://IP:4533

Crea tu cuenta de administrador

Navidrome escaneará /music automáticamente

Variables de entorno avanzadas

VariableDescripción
ND_SCANSCHEDULEFrecuencia de escaneo (15m, 1h, @every 30m)
ND_ENABLETRANSCODINGTranscodificación al vuelo (true/false)
ND_TRANSCODINGCACHESIZECaché de transcodificación (ej: 1GB)
ND_ENABLESHARINGPermitir compartir enlaces públicos
ND_ENABLEDOWNLOADSPermitir descargas desde la interfaz
ND_DEFAULTLANGUAGEIdioma por defecto (es, en, pt)
ND_ENABLESTARRATINGHabilitar valoraciones con estrellas
ND_LASTFM_APIKEYAPI key de Last.fm para scrobbling
ND_SPOTIFY_ID / SECRETPara obtener carátulas desde Spotify

Usuarios adicionales

Desde la interfaz web → Ajustes → Usuarios. Cada usuario tiene sus propias listas, favoritos e historial independiente.

Sección 07

Instalación de spotDL

spotDL es una herramienta de código abierto que busca canciones en YouTube a partir de metadatos de Spotify. Descarga todo con carátulas, artista, álbum, letras y género.

Instalación

bash
# Instalar Python y dependencias
apt install -y python3 python3-pip ffmpeg

# Instalar spotDL
pip3 install spotdl --break-system-packages

# Verificar
spotdl --version

Uso básico

bash
# Descargar una canción
spotdl download "https://open.spotify.com/track/ID_CANCION"

# Descargar playlist completa con estructura de carpetas
spotdl download "https://open.spotify.com/playlist/ID_PLAYLIST" \
  --output "/mnt/music/{artist}/{album}/{title}.{output-ext}"

Función SYNC (clave para automatización)

La función sync compara el estado actual de una playlist con lo descargado: baja las nuevas y elimina las que ya no están.

bash
# Primera vez: crear archivo de sincronización
spotdl sync "URL_PLAYLIST" \
  --save-file "/opt/spotdl/nombre.sync.spotdl" \
  --output "/mnt/music/Playlists/Nombre/{title}.{output-ext}"

# Ejecuciones posteriores: solo actualizar
spotdl sync "/opt/spotdl/nombre.sync.spotdl"
💡 Ventaja de SYNC

No re-descarga toda la playlist cada vez. Solo baja canciones nuevas y elimina las que se quitaron. Perfecto para playlists que cambian semanalmente como los Top 50.

Sección 08

Automatización con Cron Jobs

Crear directorios de trabajo

bash
mkdir -p /opt/spotdl
mkdir -p /mnt/music/Playlists
mkdir -p /var/log/spotdl

Inicializar sincronizaciones

Ejecuta una vez para crear los archivos .sync.spotdl:

bash
# Top 50 Global
spotdl sync "https://open.spotify.com/playlist/37i9dQZEVXbMDoHDwVN2tF" \
  --save-file "/opt/spotdl/top50-global.sync.spotdl" \
  --output "/mnt/music/Playlists/Top50-Global/{title}.{output-ext}"

# Top 50 USA
spotdl sync "https://open.spotify.com/playlist/37i9dQZEVXbLRQDuF5jeBp" \
  --save-file "/opt/spotdl/top50-usa.sync.spotdl" \
  --output "/mnt/music/Playlists/Top50-USA/{title}.{output-ext}"

# Top 50 España
spotdl sync "https://open.spotify.com/playlist/37i9dQZEVXbNFJfN1Vw8d9" \
  --save-file "/opt/spotdl/top50-spain.sync.spotdl" \
  --output "/mnt/music/Playlists/Top50-Spain/{title}.{output-ext}"

# Top 50 México
spotdl sync "https://open.spotify.com/playlist/37i9dQZEVXbO3qyFxbkOE1" \
  --save-file "/opt/spotdl/top50-mexico.sync.spotdl" \
  --output "/mnt/music/Playlists/Top50-Mexico/{title}.{output-ext}"

Configurar Cron

crontab — crontab -e
# Sincronizar playlists Top 50 cada día a las 3 AM
0 3 * * *   /usr/local/bin/spotdl sync /opt/spotdl/top50-global.sync.spotdl >> /var/log/spotdl/global.log 2>&1
15 3 * * *  /usr/local/bin/spotdl sync /opt/spotdl/top50-usa.sync.spotdl >> /var/log/spotdl/usa.log 2>&1
30 3 * * *  /usr/local/bin/spotdl sync /opt/spotdl/top50-spain.sync.spotdl >> /var/log/spotdl/spain.log 2>&1
45 3 * * *  /usr/local/bin/spotdl sync /opt/spotdl/top50-mexico.sync.spotdl >> /var/log/spotdl/mexico.log 2>&1
💡 ¿Por qué escalonados cada 15 min?

Ejecutar todo a la vez puede saturar tu conexión y provocar errores de throttling en YouTube. Escalonándolas se evitan bloqueos.

Sección 09

URLs Oficiales de Playlists Top 50

Estas son las playlists oficiales mantenidas por Spotify, actualizadas diariamente. Usa estas URLs con spotDL:

País / RegiónURL de Spotify
🌍 Globalhttps://open.spotify.com/playlist/37i9dQZEVXbMDoHDwVN2tF
🇺🇸 Estados Unidoshttps://open.spotify.com/playlist/37i9dQZEVXbLRQDuF5jeBp
🇪🇸 Españahttps://open.spotify.com/playlist/37i9dQZEVXbNFJfN1Vw8d9
🇲🇽 Méxicohttps://open.spotify.com/playlist/37i9dQZEVXbO3qyFxbkOE1
🇦🇷 Argentinahttps://open.spotify.com/playlist/37i9dQZEVXbMMy2roB9myp
🇨🇴 Colombiahttps://open.spotify.com/playlist/37i9dQZEVXbOa2lmxNORXQ
🇬🇧 Reino Unidohttps://open.spotify.com/playlist/37i9dQZEVXbLnolsZ8PSNw
🇫🇷 Franciahttps://open.spotify.com/playlist/37i9dQZEVXbIPWwFssbupI
🇩🇪 Alemaniahttps://open.spotify.com/playlist/37i9dQZEVXbJiZcmkrIHGU
🇧🇷 Brasilhttps://open.spotify.com/playlist/37i9dQZEVXbMXbN3EUUhlg
🇮🇹 Italiahttps://open.spotify.com/playlist/37i9dQZEVXbIQnj7RRhdSX
🇨🇱 Chilehttps://open.spotify.com/playlist/37i9dQZEVXbL0GavIqMTeb

Todas las playlists oficiales siguen el patrón 37i9dQZEVXb + identificador del país.

Sección 10

Script Maestro de Sincronización

En lugar de múltiples entradas en cron, usa un solo script que gestione todas las playlists con pausas entre descargas:

bash — /opt/spotdl/sync-all.sh
#!/bin/bash
# Script maestro de sincronización de playlists

LOG_DIR="/var/log/spotdl"
SYNC_DIR="/opt/spotdl"
MUSIC_DIR="/mnt/music/Playlists"
DATE=$(date '+%Y-%m-%d %H:%M:%S')

echo "=== Inicio sincronización: $DATE ==="

# Definir playlists
declare -A PLAYLISTS=(
  ["Top50-Global"]="37i9dQZEVXbMDoHDwVN2tF"
  ["Top50-USA"]="37i9dQZEVXbLRQDuF5jeBp"
  ["Top50-Spain"]="37i9dQZEVXbNFJfN1Vw8d9"
  ["Top50-Mexico"]="37i9dQZEVXbO3qyFxbkOE1"
  ["Top50-Argentina"]="37i9dQZEVXbMMy2roB9myp"
  ["Top50-Colombia"]="37i9dQZEVXbOa2lmxNORXQ"
)

for NAME in "${!PLAYLISTS[@]}"; do
  PLAYLIST_ID="${PLAYLISTS[$NAME]}"
  SYNC_FILE="$SYNC_DIR/$NAME.sync.spotdl"
  OUTPUT_DIR="$MUSIC_DIR/$NAME"
  URL="https://open.spotify.com/playlist/$PLAYLIST_ID"

  echo "--- Sincronizando: $NAME ---"

  if [ ! -f "$SYNC_FILE" ]; then
    spotdl sync "$URL" \
      --save-file "$SYNC_FILE" \
      --output "$OUTPUT_DIR/{title}.{output-ext}"
  else
    spotdl sync "$SYNC_FILE"
  fi

  # Pausa entre playlists para evitar throttling
  sleep 120
done

echo "=== Sincronización completada ==="
bash
# Dar permisos y agregar a cron
chmod +x /opt/spotdl/sync-all.sh

# Cron simplificado (una entrada)
crontab -e
0 3 * * * /opt/spotdl/sync-all.sh >> /var/log/spotdl/sync.log 2>&1
⚖️ Aviso Legal

spotDL descarga audio de YouTube, no de Spotify. Asegúrate de respetar las leyes de copyright de tu país. Este sistema está pensado para uso personal.

Sección 11

Acceso Remoto con Tailscale

Tailscale crea una red VPN mesh que te permite acceder a tu servidor desde cualquier lugar sin abrir puertos en tu router.

Instalar Tailscale

bash
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up

Acceso desde fuera

Instala Tailscale en tu teléfono (App Store / Play Store)

Inicia sesión con la misma cuenta

Accede a Navidrome: http://100.x.y.z:4533

HTTPS automático con Tailscale Serve

bash
tailscale serve https / http://localhost:4533
tailscale serve status

# Tu URL será algo como:
# https://navidrome.tu-tailnet.ts.net
Sección 12

Clientes Compatibles

Navidrome soporta la API Subsonic, haciéndolo compatible con más de 40 aplicaciones.

Apps Móviles

Symfonium

Android
El mejor cliente Android. Interfaz moderna, offline, CarPlay.
~$5 único

play:Sub

iOS
Excelente para iPhone. Soporte offline completo.
Gratis / Premium

Amperfy

iOS
Open source, muy completa y activamente desarrollada.
Gratis

Substreamer

Android / iOS
Multiplataforma, buena UI, soporte offline.
Gratis / Premium

DSub

Android
Clásica, fiable. Referencia en clientes Subsonic.
Gratis

Tempo

iOS
Interfaz moderna y limpia, excelente experiencia.
Gratis

Apps de Escritorio

Interfaz Web

Cualquier navegador
Incluida en Navidrome. Sin instalar nada.
Incluida

Feishin

Windows / macOS / Linux
Cliente de escritorio con interfaz tipo Spotify.
Gratis

Sublime Music

Linux
GTK nativo, ligero e integrado con el escritorio.
Gratis

Configurar un cliente

ℹ️ Datos de conexión

Servidor: http://IP:4533 (o tu URL de Tailscale)
Usuario: tu usuario de Navidrome
Contraseña: tu contraseña de Navidrome

La mayoría de clientes permiten descargar música para escucha offline.

Sección 13

Mantenimiento y Copias de Seguridad

Actualizar Navidrome

bash
cd /opt/navidrome
docker compose pull
docker compose up -d

Backup

bash
# Base de datos y config de Navidrome
tar -czf /root/backup-navidrome-$(date +%Y%m%d).tar.gz /opt/navidrome/data/

# Archivos de sincronización de spotDL
tar -czf /root/backup-spotdl-$(date +%Y%m%d).tar.gz /opt/spotdl/

Limpieza y monitoreo

bash
# Limpiar logs viejos (agregar a cron semanal)
0 0 * * 0 find /var/log/spotdl/ -name '*.log' -mtime +30 -delete

# Ver espacio usado por playlists
du -sh /mnt/music/Playlists/*

# Espacio total
df -h /mnt/music

Cada playlist Top 50 ocupa aprox. 200-400 MB (50 canciones MP3). Con 6 países: ~1.5-2.5 GB renovándose semanalmente.

Sección 14

Solución de Problemas Comunes

ProblemaSolución
No aparece música nuevaEspera al escaneo (15 min) o fuerza desde Ajustes → Escanear
spotDL error 403YouTube limita tu IP. Espera unas horas o usa --audio youtube-music
Docker no arranca en LXCVerifica nesting: pct set 200 --features nesting=1
Permisos incorrectoschown -R 1000:1000 /mnt/music o ajusta user en compose
Sin carátulasspotDL las incluye automáticamente. Navidrome también busca online
Sin transcodificaciónInstala ffmpeg: apt install ffmpeg
Cliente no conectaVerifica puerto 4533 accesible. Con Tailscale: misma tailnet
Canciones equivocadasUsa --only-verified-results para mayor precisión

Comandos de diagnóstico

bash
# Logs de Navidrome en tiempo real
docker compose -f /opt/navidrome/docker-compose.yml logs -f

# Estado del contenedor
docker ps

# Probar spotDL manualmente
spotdl download "nombre de cancion" --output /tmp/test/

# Último log de sincronización
tail -50 /var/log/spotdl/sync.log