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:
- 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”.
- Montaje dentro de la VM – La VM necesita un punto de montaje persistente. Un error en
/etc/fstabo en la identificación del disco (por ID, UUID o path) provoca que el montaje falle después de un reinicio. - 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)
- Identificar el disco en el host con
ls -l /dev/disk/by-id/. Usar el identificador permanente (ata-...-part1oscsi-...) evita que cambie el nombre de dispositivo. - 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). - Montar el disco en la VM añadiendo una entrada a
/etc/fstabbasada en UUID o LABEL. Esto asegura que el montaje sea consistente. - Exponer la ruta al contenedor mediante un bind‑mount en el
docker runo en eldocker-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)
- Crear un export NFS en el host apuntando al punto de montaje del disco.
- Montar el export dentro de la VM (
mount -t nfs host:/export /mnt/data). - 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
- Reiniciar el host y comprobar que el disco sigue asignado a la VM (
qm listmuestra el dispositivo SCSI). - Dentro de la VM, ejecutar
mount | grep /mnt/datapara confirmar que el punto de montaje está activo. - Verificar que Docker muestra el contenedor en estado
runningy que la ruta/datacontiene los archivos esperados (docker exec jellyfin ls /data). - 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.
- (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
noatimeen/etc/fstabreduce escrituras innecesarias, importante para discos HDD. - Controladores de disco: en Proxmox, usar el modelo
virtio-scsi-pciofrece mejor rendimiento queide. - Permisos de Linux: el usuario que ejecuta Docker dentro de la VM necesita permiso de lectura/escritura en
/mnt/data. Ajustar conchownosetfaclsegú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.