Problema

Muchos usuarios de NAS domésticos llegan al punto en que el firmware del fabricante se vuelve una limitación: actualizaciones forzadas, funcionalidades bloqueadas detrás de suscripciones y poca visibilidad sobre el stack subyacente. El patrón típico es querer un servidor de medios, archivos y acceso remoto que sea completamente controlable, reproducible y sin puertos públicos, pero sin renunciar a la estabilidad de un hardware barato. La pregunta recurrente es: ¿cómo montar esa infraestructura desde cero usando Debian y Docker, garantizando redundancia de discos y acceso seguro desde cualquier lugar?

Causa

Los obstáculos habituales aparecen en tres áreas:

  1. Abstracción del NAS – El software propietario oculta configuraciones de red, permisos de Samba y parámetros de transcodificación, lo que dificulta la personalización.
  2. Exposición de puertos – La mayoría de guías de Plex o Samba asumen que se abrirán puertos en el router, creando superficie de ataque innecesaria.
  3. Gestión de discos – Los usuarios confunden RAID 1 con backup y, al migrar a Linux, a menudo se topan con configuraciones de mdadm o systemd que no persisten tras reinicios.

Solución

Una arquitectura basada en Debian 13 (o cualquier versión estable) con Docker como capa de aplicación permite reproducir el mismo stack en cualquier mini‑PC. Los componentes clave son:

  • RAID 1 con mdadm para espejo de discos internos. Se crea una única unidad lógica que se monta en /mnt/storage.
  • Docker Compose que define contenedores para Plex (imagen linuxserver/plex con Quick Sync habilitado) y para Samba (dperson/samba o lscr.io/linuxserver/samba).
  • Tailscale como red privada overlay que elimina la necesidad de abrir puertos. Se configura como subnet router para que la subred local (192.168.0.0/24) sea accesible desde cualquier dispositivo autorizado.
  • smartmontools como monitor de salud de discos, enviando alertas por correo mediante msmtp.

Paso a paso resumido

  1. Instalar Debian y preparar discos

    apt update && apt install -y mdadm smartmontools
    mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc
    mkfs.ext4 /dev/md0
    mkdir -p /mnt/storage
    echo '/dev/md0 /mnt/storage ext4 defaults 0 2' >> /etc/fstab
    mount -a
    
  2. Configurar smartmontools
    Editar /etc/smartd.conf para monitorizar /dev/sdb y /dev/sdc, y apuntar a un script que use msmtp para enviar correo.

  3. Instalar Docker y Compose v2

    apt install -y docker.io
    systemctl enable --now docker
    apt install -y docker-compose-plugin
    
  4. Crear docker-compose.yml (ver bloque de código más abajo).
    Los volúmenes apuntan a /mnt/storage/media y /mnt/storage/config.

  5. Habilitar Quick Sync
    Añadir el dispositivo /dev/dri al contenedor Plex y establecer la variable PLEX_MEDIA_SERVER_HWACCEL=1.

  6. Instalar y configurar Tailscale

    curl -fsSL https://tailscale.com/install.sh | sh
    tailscale up --advertise-routes=192.168.0.0/24 --accept-routes
    sysctl -w net.ipv4.ip_forward=1
    echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/99-tailscale.conf
    
  7. Arrancar el stack

    docker compose up -d
    

Con esta combinación, Plex sirve contenido usando la iGPU del mini‑PC, Samba ofrece comparticiones por usuario y Tailscale permite acceso remoto sin que ningún puerto quede abierto en el router.

Cuándo aplicar esta solución

  • Necesitas control total sobre versiones de Plex, Samba y cualquier otro servicio.
  • Quieres evitar puertos públicos y confiar en una red overlay autenticada.
  • Dispones de al menos dos discos y buscas redundancia a nivel de bloque, no backup completo.
  • El hardware cuenta con iGPU Intel (Quick Sync) o GPU compatible con VA‑API para transcodificación.
  • No requieres UI de administración de NAS; prefieres archivos de configuración versionables.

No es la mejor opción si:

  • Solo dispones de un único disco y no puedes tolerar la pérdida de datos sin backup externo.
  • Necesitas funcionalidades específicas de Synology (por ejemplo, Snapshot Replication) que no están cubiertas por paquetes de Linux.
  • Prefieres una solución “plug‑and‑play” con panel web completo y no quieres gestionar Docker o mdadm.

Código

# docker-compose.yml (versión mínima)
services:
  plex:
    image: linuxserver/plex
    container_name: plex
    restart: unless-stopped
    network_mode: host
    environment:
      - PLEX_UID=1000
      - PLEX_GID=1000
      - TZ=America/Argentina/Buenos_Aires
      - PLEX_MEDIA_SERVER_HWACCEL=1
    devices:
      - /dev/dri:/dev/dri
    volumes:
      - /mnt/storage/config/plex:/config
      - /mnt/storage/media:/data
  samba:
    image: lscr.io/linuxserver/samba
    container_name: samba
    restart: unless-stopped
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Argentina/Buenos_Aires
      - USERID=1000
      - GROUPID=1000
    ports: []  # sin puertos expuestos
    volumes:
      - /mnt/storage/config/samba:/config
      - /mnt/storage/media:/shared
    cap_add:
      - NET_ADMIN
    command: "-s \"Media;/shared;yes;no;no;1000\""

Verificación

  1. RAID activo
    cat /proc/mdstat debe mostrar md0 en estado active sync.
  2. SMART alertas
    Forzar una prueba corta: smartctl -t short /dev/sdb y revisar /var/log/syslog por mensajes de smartd.
  3. Plex
    Acceder a http://localhost:32400/web desde la máquina local; la transcodificación debe usar h264_qsv en la pestaña de hardware.
  4. Samba
    Desde otro equipo en la red Tailscale, montar \\<tailscale-ip>\Media y crear un archivo; verificar que el UID/GID coinciden con 1000.
  5. Tailscale
    Ejecutar tailscale status y confirmar que la subred 192.168.0.0/24 aparece bajo “Routes advertised”.

Notas adicionales

  • Persistencia de mdadm – Después de crear el array, guarda la configuración con mdadm --detail --scan >> /etc/mdadm/mdadm.conf.
  • Backup fuera del sitio – RAID 1 protege contra fallos físicos, pero no contra borrados accidentales. Programa rsync o restic a un bucket S3 o a un disco externo desconectado.
  • Actualizaciones de Docker – La versión v2 del plugin se gestiona con apt upgrade. Reinicia los contenedores después de una actualización mayor del motor.
  • Tailscale ACLs – Define reglas en tailscale.com/admin/acls para limitar qué dispositivos pueden acceder a la subred del servidor.
  • Logs centralizados – Redirige los logs de Docker a journald ("log-driver": "journald" en daemon.json) y usa journalctl -u docker para depuración rápida.