Streaming está Roto III: La Fundación (SO, Docker y “Día Uno”)
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?
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.
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.
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.
Creación de Carpetas y Estructura Inicial. El script crea el árbol de directorios
/data/mediay/data/downloadscon 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!

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:
Accede al router y averigua la IP que agarró el servidor. Con esto, identificamos la Dirección MAC de nuestro MiniPC.
Asigna una IP estática (u otra que quieras) en el router (Static Lease).
Accede a él vía SSH (
ssh usuario@ip) desde tu computadora principal.Ejecuta el script
install.sh.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!
