Construyendo un Homelab Production-Ready con Raspberry Pi 5 y Docker
3 de febrero de 202618 min de lectura6 vistas

Construyendo un Homelab Production-Ready con Raspberry Pi 5 y Docker

homelabraspberry-pidockerself-hosteddevopsinfrastructurenetworkingtailscale

Durante los últimos meses, estuve construyendo y refinando un setup de homelab profesional que funciona tanto como plataforma de aprendizaje como infraestructura de producción para mis proyectos personales. Lo que empezó como un simple experimento con una Raspberry Pi evolucionó en un ecosistema robusto y self-hosted corriendo más de 13 servicios containerizados.

En este post, voy a explicar la arquitectura, el stack tecnológico, y las lecciones aprendidas al construir un homelab que compite con muchos setups cloud—todo corriendo en una sola Raspberry Pi 5.


¿Por qué construir un Homelab?

Como desarrollador trabajando con infraestructura cloud a escala (AWS Lambda, SQS, SNS en NaranjaX), quería un entorno sandbox donde pudiera:

  1. Aprender haciendo - Deployar y gestionar servicios reales, no solo tutoriales

  2. Self-hostear todo - Ser dueño de mis datos e infraestructura

  3. Reducir costos - Sin gastos mensuales en servicios básicos como VPNs, monitoring o almacenamiento

  4. Experimentar libremente - Romper cosas sin miedo al impacto en producción

  5. Integrar con proyectos personales - Deployar mamovies.io, TallerOS y otros side projects

¿El resultado? Un homelab que maneja desde bloqueo de ads a nivel de red hasta automatización de workflows, todo accesible de forma segura desde cualquier lugar del mundo.


El Stack Tecnológico

Hardware

  • Raspberry Pi 5 (8GB RAM)

  • Ubuntu Server 24.04 LTS

  • Cooling activo (mantiene temps en 45-55°C bajo carga)

  • SSD Externo 1TB (próximamente para storage persistente y backups)

Infraestructura Core

  • Docker & Docker Compose - Orquestación de containers

  • Tailscale - VPN zero-config con subnet routing (¡sin port forwarding!)

  • Nginx Proxy Manager - Reverse proxy con certificados SSL

  • Portainer - GUI de gestión de Docker

Estrategia de Networking

Todos los servicios usan dominios custom .homelab.local y son accesibles via:

  • Internamente: Acceso directo por IP via red local (192.168.1.100)

  • Remotamente: VPN Tailscale (100.99.88.77) desde cualquier lugar

  • Sin port forwarding - Cero superficie de ataque desde internet público

Este enfoque híbrido me da la conveniencia del acceso local con la seguridad de una VPN apropiada para conectividad remota.


Servicios Deployados

Infraestructura & Monitoring

Portainer - Gestión de Docker

  • Gestión visual de containers con acciones one-click

  • Deploy de stacks desde archivos YAML

  • Monitoring de uso de recursos en tiempo real

  • Acceso: https://portainer.homelab.local

Uptime Kuma - Monitoring de Servicios

  • Trackea 11 servicios con intervalos de 60 segundos

  • Tracking de uptime del 99.9% con datos históricos

  • Notificaciones webhook para downtime

  • Monitorea servicios internos y sitios externos

Netdata - Monitoring del Sistema

  • Métricas en tiempo real de CPU, RAM, disco I/O, red

  • Uso de recursos por container

  • Monitoring de temperatura con alertas

  • Dashboards hermosos con granularidad de 1 segundo

  • Stats actuales: 14% CPU promedio, 5.5GB RAM usada, 45-55°C temp

Pi-hole - Bloqueo de Ads a Nivel de Red

  • Bloqueo de ads por DNS para todos los dispositivos en la red

  • 412,498 dominios en listas de bloqueo

  • ~1% de queries filtradas (ahorra ancho de banda y privacidad)

  • Entradas DNS custom para servicios locales

Nginx Proxy Manager - Reverse Proxy

  • Ruteo limpio de dominios (sin puertos en URLs)

  • Certificados SSL via Let's Encrypt

  • Soporte WebSocket para apps en tiempo real

  • Control de acceso centralizado

Dozzle - Logs de Containers en Tiempo Real

  • UI hermosa para ver logs de todos los containers

  • Vista multi-container con filtrado

  • Búsqueda instantánea en logs

  • Sin necesidad de SSH para debugging

n8n - Motor de Automatización de Workflows

  • Alternativa self-hosted a Zapier

  • Constructor visual de workflows

  • 400+ integraciones disponibles

  • Workflows planeados: Monitoring de salud, backups automáticos, ruteo de alertas

Watchtower - Updates Automáticos

  • Chequea actualizaciones de imágenes diariamente

  • Auto-actualiza containers con rollback en caso de falla

  • Limpia imágenes viejas

  • Mantiene todo actualizado sin intervención manual


Herramientas para Developers

Stirling PDF - Toolkit de Manipulación de PDFs

  • 50+ operaciones con PDFs: merge, split, compress, rotate

  • OCR para documentos escaneados

  • Encriptación y protección con password

  • Conversión entre formatos (PDF ↔ Word, imágenes, etc)

  • Caso de uso: Procesar documentos localmente sin subirlos a servicios cloud

IT-Tools - Navaja Suiza para Developers

  • 80+ utilidades en un solo lugar

  • Encoders/Decoders: Base64, URL, JWT, HTML entities

  • Generadores: UUID, Hash, Password, Lorem Ipsum

  • Formateadores: JSON, XML, SQL, YAML

  • Conversores: JSON ↔ YAML, CSV ↔ JSON, unidades, colores

  • Herramientas crypto: Generadores de hash, encriptación

  • Herramientas de red: Calculadora IP, lookup MAC

FileBrowser - Gestor de Archivos Web

  • Acceso al filesystem de la Raspberry Pi desde el navegador

  • Upload/download de archivos con drag & drop

  • Edición de archivos de texto inline con syntax highlighting

  • Crear/renombrar/mover/eliminar archivos y carpetas

  • Caso de uso: Gestionar archivos sin SFTP o SSH

Wiki.js - Documentación Técnica

  • Wiki moderna con soporte Markdown

  • Búsqueda full-text en todas las páginas

  • Documentación organizada con tags y paths

  • Contenido actual:

    • Guía de setup (hardware, networking, servicios)
    • Referencia de Docker stacks (archivos YAML completos)
    • Cheatsheet de comandos (Docker, Tailscale, sistema)
    • Guía de troubleshooting (problemas comunes y soluciones)

Deep Dive en la Arquitectura

Networking de Docker

Todos los servicios corren en una red bridge compartida llamada homelab:

docker network create homelab

¿Por qué una red custom?

  1. DNS container-to-container - Los servicios se comunican via nombres (ej: nginxnetdata:19999)

  2. Aislamiento de red - Los containers no pueden acceder al host a menos que se configure explícitamente

  3. Service discovery fácil - No hay que trackear IPs

  4. Separación limpia - La red del host se mantiene limpia

Cada stack incluye:

networks:
  homelab:
    external: true

Esto conecta el container a la red compartida, habilitando comunicación inter-servicios sin fricción.


Flujo de Resolución de Dominios

Así es como fluye un request a través del sistema:


1. Usuario tipea: netdata.homelab.local
        ↓

2. Mac chequea /etc/hosts → encuentra: 100.99.88.77 netdata.homelab.local
        ↓

3. Request enviado a: http://100.99.88.77:80
        ↓

4. Nginx Proxy Manager (escuchando en puerto 80) recibe request con Host: netdata.homelab.local
        ↓

5. Nginx hace proxy a la red interna Docker: netdata:19999
        ↓

6. Container Netdata responde
        ↓

7. Response fluye de vuelta a través de nginx al usuario

Insight clave: Nginx usa puertos internos del container, no los expuestos en el host. Por eso el proxy forwardea a netdata:19999 aunque el container esté expuesto como 100.99.88.77:19999 en el host.


Script Custom de Dominios

Para simplificar el agregado de nuevos servicios, creé un script bash:

#!/bin/bash

# /usr/local/bin/hhost

if [ -z "$1" ]; then
    echo "❌ Error: Proporciona un nombre de servicio"
    echo "Uso: hhost netdata"
    exit 1
fi

SERVICE=$1
DOMAIN="${SERVICE}.homelab.local"
IP="100.99.88.77"
HOSTS_FILE="/etc/hosts"

if grep -q "$DOMAIN" "$HOSTS_FILE"; then
    echo "⚠️  El dominio $DOMAIN ya existe"
    exit 0
fi

echo "$IP $DOMAIN" | sudo tee -a "$HOSTS_FILE" > /dev/null
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

echo "✅ Agregado: $IP $DOMAIN"
echo "✅ DNS cache limpiado"

Uso:

hhost netdata
hhost dozzle
hhost wikijs

Este script:

  1. Agrega entrada a /etc/hosts

  2. Limpia el cache DNS

  3. Provee feedback instantáneo

Tiempo ahorrado: ~2 minutos por servicio × 13 servicios = 26 minutos


Integración con Tailscale VPN

¿Por qué Tailscale sobre VPN tradicional?

El setup de VPN tradicional requiere:

  • Port forwarding en el router

  • DNS dinámico o IP estática

  • Gestión de certificados

  • Reglas de firewall complejas

  • Exponer servicios a internet

Tailscale elimina todo esto:


# Instalar Tailscale
curl -fsSL https://tailscale.com/install.sh | sh

# Habilitar subnet routing (expone toda la red hogareña)
sudo tailscale up --advertise-routes=192.168.1.0/24 --accept-routes

# Eso es todo. Ahora accesible desde cualquier lugar:
ssh user@100.99.88.77
curl http://100.99.88.77:3000  # Homepage funciona desde un café

Cómo funciona:

  • Crea una VPN mesh entre todos tus dispositivos

  • Funciona a través de NAT/firewalls via servidores relay DERP

  • Conexiones punto-a-punto cuando es posible (baja latencia)

  • Subnet routing expone toda la red hogareña a dispositivos conectados

Beneficios de seguridad:

  • Sin puertos expuestos a internet público

  • Modelo zero-trust (dispositivos deben autenticarse)

  • Tailscale no puede desencriptar tráfico (no tienen las keys)

  • ACLs para control de acceso granular


Workflow de Deployment

Este es mi proceso para agregar un nuevo servicio (refinado a lo largo de 13 deployments):

1. Research & Planning (5 min)

  • Encontrar imagen Docker (Docker Hub, LinuxServer.io, repos oficiales)

  • Leer documentación de variables de entorno

  • Chequear requerimientos de recursos

  • Anotar requerimientos de puertos

2. Crear Stack en Portainer (10 min)

version: '3.8'

services:
  service-name:
    image: repo/image:latest
    container_name: service-name
    restart: unless-stopped
    ports:
      - host-port:container-port
    environment:
      - ENV_VAR=value
    volumes:
      - service-data:/data
    networks:
      - homelab

volumes:
  service-data:

networks:
  homelab:
    external: true

Estructura del template:

  • Definición del servicio con imagen

  • Política de restart (siempre usar unless-stopped)

  • Mapeo de puertos (host:container)

  • Configuración de entorno

  • Volumes nombrados para persistencia

  • Conectar a red homelab

3. Deploy & Verificar (3 min)


# Chequear logs via Dozzle o CLI
docker logs -f service-name

# Verificar que esté corriendo
docker ps | grep service-name

# Test de acceso directo
curl http://100.99.88.77:host-port

4. Configurar Reverse Proxy (5 min)

En Nginx Proxy Manager:

  • Domain: service-name.homelab.local

  • Scheme: http (tráfico interno)

  • Forward Hostname/IP: service-name (nombre del container)

  • Forward Port: container-port (puerto interno, ¡no puerto del host!)

  • WebSockets: Habilitar si el servicio necesita updates en tiempo real

5. Agregar Entrada DNS (1 min)

hhost service-name

6. Agregar a Dashboard Homepage (2 min)


# En Homepage services.yaml

- Service Name:
    href: http://service-name.homelab.local
    description: Qué hace
    icon: icon-name

7. Documentar en Wiki.js (5 min)

  • Agregar a página Docker Stacks con YAML completo

  • Anotar cualquier configuración especial

  • Documentar tips de troubleshooting descubiertos durante setup

Tiempo total: ~30 minutos por servicio


Estrategia de Monitoring

Uso un enfoque de monitoring de tres niveles:

Nivel 1: Disponibilidad (Uptime Kuma)

  • Qué: Chequeos HTTP/HTTPS cada 60 segundos

  • Propósito: Saber inmediatamente cuando un servicio cae

  • Alertas: Webhook a Telegram planeado

  • Monitoreado: 11 servicios web + sitios externos

Nivel 2: Salud del Sistema (Netdata)

  • Qué: Métricas de sistema y containers en tiempo real

  • Propósito: Identificar cuellos de botella de recursos

  • Métricas trackeadas:

    • Uso de CPU por core y por container
    • Uso de RAM (sistema + containers)
    • I/O y espacio de disco
    • Throughput de red
    • Sensores de temperatura
  • Alertas configuradas:

    • Temperatura > 70°C (warning)
    • Temperatura > 80°C (crítico)
    • CPU > 90% por 5+ minutos
    • Disco > 85% lleno

Nivel 3: Logs de Aplicación (Dozzle)

  • Qué: Agregación de logs en tiempo real

  • Propósito: Debuggear issues y tracear errores

  • Features:

    • Vista multi-container
    • Búsqueda/filtrado instantáneo
    • Modo tail (updates en vivo)
    • Logs históricos

Ejemplo de workflow de debugging:

  1. Uptime Kuma detecta servicio caído

  2. Chequear Netdata por issues de recursos (¿OOM? ¿CPU spike?)

  3. Ver logs en Dozzle para ver mensajes de error

  4. Arreglar issue y reiniciar container

  5. Verificar recuperación en Uptime Kuma


Performance & Uso de Recursos

Stats actuales (13 containers corriendo):

MétricaValorNotas
CPU Promedio14%Picos al 30% durante updates de Watchtower
RAM Usada5.5GB / 8GB~70% utilización
Temperatura45-55°CCooling pasivo + case
Disco I/OBajoLa mayoría de servicios son CPU-bound
Red200KB/s in, 20KB/s outMayormente tráfico interno
Uptime161 díasÚltimo reboot: actualización de sistema

Containers más pesados:

  1. Wiki.js + PostgreSQL - 800MB RAM (overhead de base de datos)

  2. Netdata - 300MB RAM (retención de métricas)

  3. n8n - 250MB RAM (motor de workflows)

  4. Homepage - 150MB RAM (acceso a Docker socket)

Containers más livianos:

  1. Watchtower - 20MB RAM (mayormente idle)

  2. IT-Tools - 30MB RAM (sitio estático)

  3. Dozzle - 40MB RAM (logs read-only)

Consumo de energía: ~5W idle, ~8W bajo carga
Costo mensual de electricidad: ~$1.50 (asumiendo $0.12/kWh)


Lecciones Aprendidas

Lo que salió bien ✅

Tailscale es un game-changer

  • Setup de acceso remoto: 5 minutos vs horas para VPN tradicional

  • Funciona en todas partes: detrás de NAT, con datos móviles, en cafés

  • Sin mantenimiento: sin certificados que renovar, sin port forwarding que se rompa

El networking de Docker "simplemente funciona"

  • Nombres de containers como DNS elimina trackeo de IPs

  • Red compartida hace la comunicación inter-servicios trivial

  • Aislamiento de red mejora la seguridad

Wiki.js para documentación es esencial

  • Markdown hace la escritura de docs rápida

  • La búsqueda encuentra respuestas al instante

  • Organizar por path (homelab/setup, homelab/troubleshooting) escala bien

  • El tagging agrega otra dimensión de organización

Portainer hace Docker accesible

  • GUI para tareas rápidas (restart, ver logs, chequear recursos)

  • CLI cuando se necesita precisión (operaciones bulk, scripting)

  • Templates de stacks aceleran deployment

  • Loguear en la web UI es más rápido que SSH para chequeos casuales

Watchtower elimina el trabajo de actualización

  • Ahorra horas de trabajo manual de "chequear actualizaciones"

  • Rollback automático en caso de falla previene servicios rotos

  • Corre durante horas de bajo tráfico (schedule configurable)

El dashboard Homepage es la "puerta de entrada"

  • Un solo bookmark da acceso a todo

  • Status visual hace el health check instantáneo

  • Agregar nuevos servicios lleva 30 segundos


Desafíos Superados ❌

Issues de conexión de base de datos en BookStack

  • Problema: Necesitaba password literal <yourdbpass> por bug de LinuxServer.io

  • Solución: Cambié a Wiki.js (mejor UX de todas formas)

  • Lección: No gastes horas debuggeando issues conocidos—cambia de herramienta

Complicaciones de reverse proxy en Pi-hole

  • Problema: Pi-hole valida el Host header, rechaza requests de proxy

  • Solución: Acceso via IP directa (http://100.99.88.77:8080/admin)

  • Lección: No todo necesita estar detrás de un proxy

Confusión de autenticación en FileBrowser

  • Problema: Credenciales default no funcionaban

  • Solución: Password random impresa en logs en el primer inicio (por diseño)

  • Lección: Siempre chequear logs antes de asumir que las cosas están rotas

Mismatch de versión API en Watchtower

  • Problema: client version 1.25 is too old, need 1.44

  • Solución: Setear variable de entorno DOCKER_API_VERSION=1.44

  • Lección: El versionado de la API de Docker puede causar breakage sutil

Puertos internos vs externos en Nginx

  • Problema: Servicios no accesibles via proxy a pesar de config correcta

  • Solución: Usar puerto interno del container, no puerto expuesto del host

  • Ejemplo: Forwardear a netdata:19999 no netdata:19999 (aunque el host exponga 19999)

  • Lección: El mapeo de puertos de Docker crea dos namespaces de puertos separados


Consideraciones de Seguridad

Postura de seguridad actual:

Sin exposición de puertos públicos - Solo VPN Tailscale
Segmentación de red - La red Docker aísla containers
Updates automáticos - Watchtower parchea vulnerabilidades
HTTPS para servicios sensibles - Portainer usa TLS
Passwords fuertes - Generadas, almacenadas en password manager

Mejoras planeadas:

🔜 Fail2ban - Banear IPs después de intentos fallidos de SSH
🔜 Vaultwarden - Password manager self-hosted para todas las credenciales
🔜 Authentik - SSO con 2FA para todos los servicios
🔜 Backups automáticos - Storage encriptado offsite

Modelo de amenazas:

  • In-scope: Protección contra ataques oportunistas, leaks de credenciales

  • Out-of-scope: Actores de estado-nación, ataques de acceso físico

  • Riesgo aceptable: Compromiso de red hogareña (todos los dispositivos ya en misma LAN)


Planes de Expansión Futura

Corto Plazo (Próximo Mes)

Workflows de n8n

  • Workflow de health check: pingear todos los servicios, alertar si caen

  • Workflow de backup: snapshots diarios a cloud storage

  • Reporte de Pi-hole: resumen diario de ads bloqueados y dominios top

  • Workflow de auto-restart: webhook de Uptime Kuma → reiniciar container fallido

Grafana + Prometheus

  • Recolectar métricas de todos los servicios

  • Crear dashboards custom (CPU por servicio, red por container, etc)

  • Configurar reglas de alertas

  • Análisis de datos históricos (identificar tendencias)

Bot de Telegram

  • Recibir alertas de sistemas de monitoring

  • Consultar status del sistema: /status, /temp, /uptime

  • Disparar acciones: /restart netdata, /update all


Mediano Plazo (Próximos 3 Meses)

Storage & Backups (cuando llegue el SSD 1TB)

  • Duplicati o Restic - Backups automáticos encriptados a Backblaze B2 o Google Drive

  • MinIO - Object storage S3-compatible para proyectos

  • Share Samba - Network drive accesible desde Mac/Windows

Autenticación & Seguridad

  • Vaultwarden - Servidor Bitwarden self-hosted

  • Authentik - Single Sign-On con 2FA para todos los servicios

  • Fail2ban - Baneo automático de IPs después de logins fallidos

Gestión de Media

  • Jellyfin - Netflix personal para películas/series

  • Audiobookshelf - Servidor de audiobooks y podcasts

  • Navidrome - Streaming de música (alternativa a Spotify)


Largo Plazo (6+ Meses)

Herramientas de Desarrollo

  • Gitea - Servidor Git privado para repos personales

  • Code-Server - VS Code en navegador (codear desde iPad, teléfono, donde sea)

  • Drone CI - Integración continua para testing y deployment automatizado

Smart Home (si me meto en IoT)

  • Home Assistant - Hub central para dispositivos smart

  • Node-RED - Editor visual de automatización (luces, temp, sensores)

  • Zigbee2MQTT - Controlar dispositivos Zigbee sin hubs propietarios

Monitoring Avanzado

  • Loki + Promtail - Agregación de logs con búsqueda full-text

  • Elasticsearch + Kibana - Análisis avanzado de logs

  • Alertmanager - Ruteo y silenciado centralizado de alertas


Análisis de Costos

Costos únicos:

  • Raspberry Pi 5 (8GB): $80

  • Case + cooling: $20

  • Fuente de alimentación: $12

  • Total hardware: $112

Costos recurrentes:

  • Electricidad (~5W promedio): $1.50/mes

  • Total mensual: $1.50

Comparación de costos vs alternativas cloud:

ServicioCosto CloudCosto Self-Hosted
Uptime monitoring (UptimeRobot Pro)$7/mes$0
VPN (NordVPN)$12/mes$0
Password manager (1Password)$5/mes$0 (planeado)
Automation (Zapier Starter)$20/mes$0
Documentation (Notion Pro)$8/mes$0
File storage 1TB (Google Drive)$10/mes$0 (SSD próximamente)
Total$62/mes$1.50/mes

Periodo de recuperación: ~2 meses
Ahorro anual: $726


Conclusiones Clave

Lecciones Técnicas

  1. Empezar pequeño, iterar - No intentes deployar todo de una. Construí incrementalmente.

  2. Documentar sobre la marcha - Wiki.js me ahorró horas de investigar "¿cómo configuré eso?"

  3. La automatización vale la pena - Scripts como hhost parecen triviales pero ahorran tiempo compuesto

  4. El monitoring no es opcional - No podés arreglar lo que no podés ver. Configurá monitoring temprano.

  5. Usar redes gestionadas - El bridge networking de Docker elimina tanta configuración manual

Filosofía de Infraestructura

  1. Seguridad por arquitectura - Usar VPN apropiada (Tailscale), no port forwarding

  2. Simplicidad sobre cleverness - Si es difícil de mantener, se va a romper cuando estés ocupado

  3. Redundancia donde importa - Monitoring de tres niveles atrapa issues en diferentes capas

  4. La documentación es infraestructura - Sistemas no documentados se vuelven inmanejables

  5. Los backups son obligatorios - Si los datos importan, necesitan backup (próximamente con SSD)


Recursos

Comunidades

Imágenes Docker

Recursos de Aprendizaje

Mi Setup

  • Todos los docker-compose files disponibles en Wiki.js

  • Guía de troubleshooting documentada

  • Cheatsheet de comandos


Conclusión

Construir este homelab ha sido uno de los proyectos técnicos más gratificantes que emprendí. Me enseñó más sobre networking, containerización, reverse proxies y gestión de infraestructura que cualquier serie de tutoriales.

Las mejores partes:

  • Cuesta casi nada - $1.50/mes de electricidad

  • Escala según necesidad - Agregar servicios en minutos

  • Control completo - Mis datos, mis reglas

  • Gran plataforma de aprendizaje - Experimentar sin miedo

Si estás considerando construir tu propio homelab:

Empezá con un servicio que realmente uses:

  • Bloqueo de ads (Pi-hole) si los ads te molestan

  • File browser si usás SSH seguido

  • Media server si tenés media local

  • Password manager si reutilizás passwords

Una vez que veas el valor, naturalmente vas a expandir. La infraestructura (Docker, networking, monitoring) que construís para el primer servicio hace que agregar los próximos 12 servicios sea trivial.

Mi próximo desafío: Integrar este homelab con mis proyectos de producción (automatización de mamovies.io, analytics pipeline de TallerOS).

¡Happy self-hosting! 🚀


Hardware: Raspberry Pi 5 (8GB) | OS: Ubuntu Server 24.04 | Servicios: 13 containers

Posts Relacionados