Construyendo un Homelab Production-Ready con Raspberry Pi 5 y Docker
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:
-
Aprender haciendo - Deployar y gestionar servicios reales, no solo tutoriales
-
Self-hostear todo - Ser dueño de mis datos e infraestructura
-
Reducir costos - Sin gastos mensuales en servicios básicos como VPNs, monitoring o almacenamiento
-
Experimentar libremente - Romper cosas sin miedo al impacto en producción
-
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?
-
DNS container-to-container - Los servicios se comunican via nombres (ej:
nginx→netdata:19999) -
Aislamiento de red - Los containers no pueden acceder al host a menos que se configure explícitamente
-
Service discovery fácil - No hay que trackear IPs
-
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:
-
Agrega entrada a
/etc/hosts -
Limpia el cache DNS
-
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:
-
Uptime Kuma detecta servicio caído
-
Chequear Netdata por issues de recursos (¿OOM? ¿CPU spike?)
-
Ver logs en Dozzle para ver mensajes de error
-
Arreglar issue y reiniciar container
-
Verificar recuperación en Uptime Kuma
Performance & Uso de Recursos
Stats actuales (13 containers corriendo):
| Métrica | Valor | Notas |
|---|---|---|
| CPU Promedio | 14% | Picos al 30% durante updates de Watchtower |
| RAM Usada | 5.5GB / 8GB | ~70% utilización |
| Temperatura | 45-55°C | Cooling pasivo + case |
| Disco I/O | Bajo | La mayoría de servicios son CPU-bound |
| Red | 200KB/s in, 20KB/s out | Mayormente tráfico interno |
| Uptime | 161 días | Último reboot: actualización de sistema |
Containers más pesados:
-
Wiki.js + PostgreSQL - 800MB RAM (overhead de base de datos)
-
Netdata - 300MB RAM (retención de métricas)
-
n8n - 250MB RAM (motor de workflows)
-
Homepage - 150MB RAM (acceso a Docker socket)
Containers más livianos:
-
Watchtower - 20MB RAM (mayormente idle)
-
IT-Tools - 30MB RAM (sitio estático)
-
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:19999nonetdata: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:
| Servicio | Costo Cloud | Costo 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
-
Empezar pequeño, iterar - No intentes deployar todo de una. Construí incrementalmente.
-
Documentar sobre la marcha - Wiki.js me ahorró horas de investigar "¿cómo configuré eso?"
-
La automatización vale la pena - Scripts como
hhostparecen triviales pero ahorran tiempo compuesto -
El monitoring no es opcional - No podés arreglar lo que no podés ver. Configurá monitoring temprano.
-
Usar redes gestionadas - El bridge networking de Docker elimina tanta configuración manual
Filosofía de Infraestructura
-
Seguridad por arquitectura - Usar VPN apropiada (Tailscale), no port forwarding
-
Simplicidad sobre cleverness - Si es difícil de mantener, se va a romper cuando estés ocupado
-
Redundancia donde importa - Monitoring de tres niveles atrapa issues en diferentes capas
-
La documentación es infraestructura - Sistemas no documentados se vuelven inmanejables
-
Los backups son obligatorios - Si los datos importan, necesitan backup (próximamente con SSD)
Recursos
Comunidades
-
r/selfhosted - 500k+ miembros compartiendo proyectos de homelab
-
r/homelab - Gear enterprise y setups avanzados
-
Awesome Self-Hosted - Lista curada de 1000+ servicios
Imágenes Docker
-
LinuxServer.io - Containers bien mantenidos y estandarizados
-
Docker Hub - Imágenes oficiales y contribuciones de la comunidad
-
Portainer Template Library - Stacks pre-configurados
Recursos de Aprendizaje
-
Docker Documentation - Referencia oficial
-
Tailscale Docs - Guías de setup VPN
-
Nginx Proxy Manager - Tutoriales de reverse proxy
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

