Problema

En entornos homelab es frecuente combinar Proxmox como hipervisor, máquinas virtuales (VM) para aislar servicios y Docker para empaquetar aplicaciones como Jellyfin. Cuando se dispone de un disco HDD de varios terabytes con datos ya existentes, surge la necesidad de que esos datos estén disponibles dentro de un contenedor Docker que se ejecuta en una VM. La cuestión central es decidir la mejor forma de exponer el disco sin reformatearlo ni perder información, y garantizar que la solución sea estable tras reinicios tanto del host como de la VM.

Causa

Los obstáculos típicos provienen de tres áreas:

  1. Visibilidad del bloque – Proxmox controla los dispositivos de bloque; una VM solo ve discos que el hipervisor le asigna explícitamente. Si el disco se pasa como dispositivo PCI o SCSI, la VM lo trata como un disco “crudo”.
  2. Montaje dentro de la VM – La VM necesita un punto de montaje persistente. Un error en /etc/fstab o en la identificación del disco (por ID, UUID o path) provoca que el montaje falle después de un reinicio.
  3. Exposición al contenedor – Docker necesita un bind‑mount o un volumen que apunte al punto de montaje de la VM. Si la ruta cambia o el disco se desmonta, el contenedor pierde acceso y puede lanzar errores de “volume not found”.

En paralelo, la alternativa de compartir el disco mediante NFS o Samba introduce dependencias de red y capas de permisos que pueden complicar la latencia de medios multimedia.

Solución

1. Passthrough de bloque (enfoque recomendado)

  1. Identificar el disco en el host con ls -l /dev/disk/by-id/. Usar el identificador permanente (ata-...-part1 o scsi-...) evita que cambie el nombre de dispositivo.
  2. Asignar el disco a la VM con qm set. Se crea un dispositivo SCSI que la VM verá como /dev/sdb (o el número que corresponda).
  3. Montar el disco en la VM añadiendo una entrada a /etc/fstab basada en UUID o LABEL. Esto asegura que el montaje sea consistente.
  4. Exponer la ruta al contenedor mediante un bind‑mount en el docker run o en el docker-compose.yml. No se crea un volumen Docker independiente; el contenedor usa directamente el punto de montaje de la VM.

2. Compartir vía NFS/Samba (alternativa)

  1. Crear un export NFS en el host apuntando al punto de montaje del disco.
  2. Montar el export dentro de la VM (mount -t nfs host:/export /mnt/data).
  3. Bind‑mount la ruta en Docker como antes.

Esta opción es útil si varios VMs deben acceder al mismo disco, pero añade latencia y requiere gestión de permisos de red.

Cuándo aplicar esta solución

  • Passthrough es la mejor elección cuando el disco es exclusivo para una sola VM y la carga de trabajo (por ejemplo, streaming de video) necesita acceso directo y de alta velocidad.
  • NFS/Samba conviene si el disco debe ser consumido por varias VMs o contenedores en hosts diferentes, o si la VM no tiene control total sobre el hardware (por ejemplo, en entornos de nube).
  • Evite el passthrough si la VM corre sobre un controlador de disco que no soporta passthrough de forma estable (algunas configuraciones de RAID pueden presentar problemas).
  • No aplique ninguna de las dos si el disco está en uso por el host para otras tareas críticas; en ese caso, migre los datos a un pool de almacenamiento gestionado por Proxmox.

Código

# 1. Identificar el disco en Proxmox
ls -l /dev/disk/by-id/ | grep -i 2tb

# 2. Asignar el disco a la VM (reemplaza <VMID> y el path correcto)
qm set <VMID> -scsi1 /dev/disk/by-id/ata-YourDiskSerial

# 3. Dentro de la VM: obtener UUID del particionado
blkid /dev/sdb1

# 4. Añadir a /etc/fstab (ejemplo usando UUID)
UUID=1234-ABCD  /mnt/data  ext4  defaults,noatime  0  2

# 5. Montar inmediatamente
mount /mnt/data

# 6. Ejecutar el contenedor Docker con bind‑mount
docker run -d \
  --name jellyfin \
  -v /mnt/data:/data \
  -p 8096:8096 \
  jellyfin/jellyfin:latest

Verificación

  1. Reiniciar el host y comprobar que el disco sigue asignado a la VM (qm list muestra el dispositivo SCSI).
  2. Dentro de la VM, ejecutar mount | grep /mnt/data para confirmar que el punto de montaje está activo.
  3. Verificar que Docker muestra el contenedor en estado running y que la ruta /data contiene los archivos esperados (docker exec jellyfin ls /data).
  4. Probar la reproducción en Jellyfin o cualquier otro servicio que use el volumen; la ausencia de errores de I/O indica que el passthrough funciona correctamente.
  5. (Opcional) Simular un fallo de red desmontando NFS (si se usó) y observar que el contenedor pierde acceso, confirmando la diferencia de comportamiento.

Notas adicionales

  • Backup previo: aunque el passthrough no formatea el disco, siempre es prudente crear una copia de seguridad de los datos críticos antes de manipular particiones o cambiar el controlador.
  • Cache de escritura: habilitar noatime en /etc/fstab reduce escrituras innecesarias, importante para discos HDD.
  • Controladores de disco: en Proxmox, usar el modelo virtio-scsi-pci ofrece mejor rendimiento que ide.
  • Permisos de Linux: el usuario que ejecuta Docker dentro de la VM necesita permiso de lectura/escritura en /mnt/data. Ajustar con chown o setfacl según convenga.
  • Snapshots: si la VM tiene snapshots habilitados, el disco passthrough no se incluye en los snapshots de Proxmox; los snapshots solo cubren los discos virtuales de la VM.
  • Escalabilidad: para futuros discos, repetir el proceso con un nuevo identificador; la configuración es idéntica, lo que permite escalar sin reescribir scripts.