Streaming está Roto III: La Fundación (SO, Docker y “Día Uno”)

Esta publicación fue originalmente escrita en inglés. La traducción puede no reflejar el 100% de las ideas originales del autor.

Ahora que tenemos nuestro hardware, podemos comenzar con la configuración del sistema de nuestro servidor. El MiniPC que compré venía con Windows instalado. También es posible usar el sistema de Microsoft para lo que queremos, pero es un desperdicio ridículo de rendimiento y energía.

Un Home Server robusto no es una computadora de escritorio que se queda encendida todo el día: es un sistema dedicado. Construiremos la base de software desde cero, transformando el mini PC en una infraestructura de nivel empresarial, lista para funcionar 24/7 sin intervención humana.

Elegir y Configurar el Sistema Operativo

Pero… ¿por qué no Windows? Windows consume alrededor de 2GB a 4GB de RAM solo para existir y ejecutar su interfaz gráfica. En nuestro N100, eso es un desperdicio, como dije, es tirar rendimiento a la basura. Además, Docker en Windows (vía WSL2) añade una capa de virtualización que puede afectar el rendimiento de E/S y de red.

No uses Windows. Olvídate de esta basura.

Aquí podemos usar cualquier Linux… sin interfaz. Un servidor no necesita un ratón, ventanas o fondos de pantalla.

Instalaremos Ubuntu Server sin interfaz gráfica. El servidor será controlado 100% vía terminal (SSH) desde tu PC principal. Esto asegura que cada ciclo de CPU y megabyte de RAM esté dedicado a lo que importa: tus servicios.

Por supuesto, instalar Ubuntu desde cero añadirá algunas capas de complejidad (no muchas). Actualizar repositorios, instalar dependencias, configurar permisos de usuario, editar archivos del sistema… Ahí es donde las cosas pueden salir mal y aparecen errores que te cuestan caro meses después.

Para esto, hice un pequeño script que automatizará todas estas configuraciones iniciales. El código es autoexplicativo.

#!/bin/bash

if [ "$EUID" -ne 0 ]; then
  echo "Please run as root (sudo ./install.sh)"
  exit 1
fi

REAL_USER=$SUDO_USER
if [ -z "$REAL_USER" ]; then
  echo "Could not detect sudo user. Exiting."
  exit 1
fi

USER_UID=$(id -u $REAL_USER)
USER_GID=$(id -g $REAL_USER)
USER_HOME=$(getent passwd $REAL_USER | cut -d: -f6)
BASE_DIR="$USER_HOME/EmuleVision"

echo "Starting installation for user: $REAL_USER"
echo "Base Directory: $BASE_DIR"

apt update && apt upgrade -y
apt install -y curl gnupg ca-certificates lsb-release cifs-utils samba vim git net-tools intel-media-va-driver-non-free libmfx1 vainfo

if ! command -v docker &> /dev/null; then
    mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
    apt update
    apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    usermod -aG docker $REAL_USER
fi

usermod -aG render $REAL_USER
usermod -aG video $REAL_USER

mkdir -p $BASE_DIR/{downloads/torrents,media/{movies,tv,manga},books}
mkdir -p $BASE_DIR/Settings/{Qbittorrent,Prowlarr,Sonarr,Radarr,Jellyfin,Gluetun,Portainer,Homepage,Scrutiny,AdGuard,Kaizoku,Kavita,CalibreWeb,Filebrowser}

chown -R $REAL_USER:$REAL_USER $BASE_DIR
chmod -R 775 $BASE_DIR

cat <<EOF >> /etc/sysctl.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
EOF
sysctl -p

sed -r -i.orig 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf
sed -r -i 's/#?DNS=/DNS=1.1.1.1 8.8.8.8/g' /etc/systemd/resolved.conf
rm -f /etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
systemctl restart systemd-resolved

cat <<EOF >> /etc/samba/smb.conf

[EmuleVision]
   path = $BASE_DIR
   writeable = yes
   guest ok = no
   create mask = 0775
   directory mask = 0775
   valid users = $REAL_USER
   force user = $REAL_USER
EOF

echo "Set SMB password for $REAL_USER:"
smbpasswd -a $REAL_USER
systemctl restart smbd

TZ=$(timedatectl show -p Timezone --value)

cat <<EOF > $BASE_DIR/.env
PUID=$USER_UID
PGID=$USER_GID
TZ=$TZ
VPN_USER=vpn_username_here
VPN_PASS=vpn_password_here
EOF

chown $REAL_USER:$REAL_USER $BASE_DIR/.env

echo "Installation complete."
echo "1. Edit $BASE_DIR/.env with your VPN credentials."
echo "2. Place your docker-compose.yml in $BASE_DIR."
echo "3. Reboot the system."

¿Qué hace el script?

  1. Docker Nativo. Instala el Docker Engine directamente desde la fuente oficial, asegurando la versión más reciente y segura, sin depender de paquetes obsoletos de la distribución. Intentar hacer esto en Windows con WSL es pedir un dolor de cabeza.

  2. Controladores Intel QuickSync. Ubuntu Server viene con controladores genéricos, lo que afectará directamente el rendimiento de nuestro N100 para la transcodificación de video. El script instala el intel-media-va-driver-non-free y configura los permisos de renderizado (grupo render), asegurando que Jellyfin tenga acceso directo al hardware.

  3. Eliminación de IPv6. Más adelante me centraré específicamente en la parte de seguridad, ya que en mi caso elegí proteger mi homeserver con una VPN. Esto es opcional, pero garantiza la privacidad de tu servidor, especialmente si planeas “adquirir” películas o series por métodos alternativos. El script deshabilita IPv6 directamente en el Kernel de Linux (sysctl.conf). De esta manera, ni Docker, ni la VPN, ni qBittorrent pueden usar IPv6, eliminando físicamente la posibilidad de una fuga. Recuerda, las fugas de IP vía IPv6 son la falla de seguridad número uno en las VPNs domésticas.

  4. Creación de Carpetas y Estructura Inicial. El script crea el árbol de directorios /data/media y /data/downloads con los permisos de usuario correctos (PUID/PGID). Si esto se hace mal ahora, los Hardlinks (copias instantáneas sin duplicar espacio) fallarán. Hablaremos más sobre este tipo de copia en la próxima publicación.

Con esto, ¡nuestro servidor está listo, seguro y optimizado en 2 minutos!

¡Mantenlo simple!

PD: Llamé a este proyecto EmuleVision. Cámbialo a lo que quieras.

Configurando una IP Estática (La Forma Correcta)

Nuestro servidor necesita una IP Estática, eso es obvio. Si la IP sigue cambiando con cada reinicio, nuestro televisor perderá la referencia a nuestro servidor con cada cambio de IP realizado por el DHCP del router. Hay dos formas de hacer esto: la forma incorrecta y la forma correcta.

  • La forma incorrecta. Configurar una IP estática solo en el SO. Básicamente, esto significaría configurar la IP estática dentro del archivo de red de Ubuntu (netplan). Esto funciona bien hasta que cambias tu router o llevas tu servidor a otra casa. Entonces tendrás que conectar un teclado y HDMI para reconfigurarlo manualmente. Recuerda: no queremos una interfaz gráfica en nuestro servidor.

  • La forma correcta. Cambiamos la configuración de Reserva DHCP/Static Lease directamente en el router, sin tocar nuestro SO. Configuramos el router para que siempre asigne la misma IP (por ejemplo, 192.168.1.50) a la Dirección MAC del servidor. De esta manera el servidor permanece en modo “Automático” (DHCP). Si cambias de red, obtiene una nueva IP y funciona inmediatamente. La gestión está centralizada en el router.

Para Resumir

Después de la instalación física (solo cables de alimentación y red) y del SO, el flujo de trabajo es quirúrgico:

  1. Accede al router y averigua la IP que agarró el servidor. Con esto, identificamos la Dirección MAC de nuestro MiniPC.

  2. Asigna una IP estática (u otra que quieras) en el router (Static Lease).

  3. Accede a él vía SSH (ssh usuario@ip) desde tu computadora principal.

  4. Ejecuta el script install.sh.

  5. Reinicia para aplicar los bloqueos del Kernel y los Controladores.

En la próxima publicación, cubriremos la privacidad y seguridad del servidor. Es opcional, pero como dicen, cada perro conoce su propia cola. En otras palabras, ¡protege tu servidor!

Adiós