Mi homelab en Docker Compose y Tailscale (sin abrir un solo puerto)

#homelab#docker#tailscale#linux

En marzo de 2024 escribí Empezando Homelab Project . Era la foto de un punto de partida: un PC nuevo, Arch Linux, la idea de virtualizar Proxmox sobre KVM y una lista de servicios soñados que iba desde Plex hasta pfSense, pasando por Wazuh y TrueNAS.

Han pasado dos años y medio y casi nada de aquello sobrevive tal cual.

Lo que sí sobrevive es lo que aprendí por el camino. Hoy soy capaz de hacer un deploy de casi cualquier cosa, entender la mayoría de las piezas que hay debajo y, sobre todo, saber cuándo algo sobra. Como en la mayoría de relatos de homelab que leo, ha sido un viaje bonito de mirar hacia atrás.

Y ese es el motivo de este post. Con Claude Code y la IA en general, hoy es facilísimo decir “móntame este servicio” y tenerlo funcionando en diez minutos. Pero sin las bases de redes, Docker y Linux, es igual de fácil acabar perdido entre configuraciones que no entiendes y que, tarde o temprano, se rompen.

Así que voy a contar qué tengo, por qué está como está, y qué me ha dado todo esto.

¿Necesito Proxmox para un homelab?

No. Si eres un solo usuario, con dos o tres dispositivos, y quieres servicios como Nextcloud, Immich o Jellyfin para ti, Docker Compose sobre una distribución Linux normal es suficiente.

Proxmox tiene sentido cuando necesitas varias máquinas virtuales aisladas, tienes varios equipos físicos, o quieres practicar virtualización porque te interesa profesionalmente. Para un homelab doméstico de uso personal, añade una capa de complejidad y consume recursos base a cambio de una flexibilidad que probablemente nunca uses.

Lo digo con conocimiento de causa, porque yo pasé por ahí.

Mi etapa Proxmox: sobrecomplicarlo todo

En su día no quise convertir el host en Proxmox, así que lo instalé dentro de una máquina virtual con KVM. Esa decisión ya me complicó la vida desde el primer día.

Para pasarle la GPU a Immich y usar la búsqueda por inteligencia artificial, tuve que pelearme con el passthrough. Para tener almacenamiento decente, me hice con un disco externo y monté un pool. Y para que todo se viera entre sí, un bridge de red propio.

Dentro de Proxmox tenía varias máquinas virtuales, un router virtual con OPNsense (llegué a instalarlo y funcionaba, pero era añadir demasiada complejidad a lo que yo tenía) y un puñado de servicios que en realidad no necesitaba. Más tarde quité Proxmox y me quedé con virt-manager a secas: máquinas virtuales sueltas, cada una conectada por Tailscale.

Fue un aprendizaje real y no me arrepiento. En aquel momento, además, las configuraciones no eran tan fáciles de resolver como ahora con una IA al lado: eran horas de documentación, foros y Reddit.

Pero no hubo una gota que colmara el vaso. Lo que pasó es que, en paralelo, iba usando Docker y lo veía absurdamente sencillo. Y después de tantas horas debugueando y arreglando cosas, uno se olvida de que el homelab está para usarlo.

Al principio está guay mantenerlo, actualizarlo, que se complique. Luego simplemente quieres que las cosas funcionen.

¿Docker Compose es suficiente para un homelab?

Sí, para la inmensa mayoría de casos domésticos.

Un archivo docker-compose.yml por servicio te da deploy y apagado en un comando, redes internas aisladas entre contenedores, volúmenes para los datos y una comunidad enorme que ya ha escrito el compose de casi cualquier cosa que quieras montar. Lo que no te da es aislamiento a nivel de sistema operativo ni virtualización completa. Para un uso personal, rara vez lo necesitas.

CriterioProxmox / máquinas virtualesDocker Compose
Consumo baseUn hipervisor y un kernel completo por VMSolo los procesos de cada contenedor
Complejidad inicialAlta: red, almacenamiento, passthrough, backupsBaja: un archivo YAML por servicio
Curva de aprendizajeVirtualización, redes virtuales, ZFS/LVMImágenes, volúmenes, redes de Docker
MantenimientoActualizar hipervisor y cada sistema invitadodocker compose pull y up -d
AislamientoCompleto (kernel propio por VM)A nivel de proceso (kernel compartido)
Cuándo tiene sentidoVarios equipos, VMs aisladas, practicar virtualizaciónUn usuario, pocos dispositivos, servicios personales

También asomé la cabeza a Kubernetes y Docker Swarm. Los descarté rápido: no eran para mí y, además, tampoco tengo más equipos que orquestar. Un solo host no justifica un orquestador.

¿Recomendaría pasar por Proxmox aunque luego lo abandones? Yo diría que no. Docker es realmente sencillo, te da esa facilidad de encender y apagar servicios, y con Tailscale accedes a todo desde tu propia VPN sin exponer nada. Si en algún momento necesitas una máquina virtual, levantas una con virt-manager al lado. Es justo lo que hago yo con Pi-hole.

Mi homelab hoy

Sigue siendo el mismo PC del post de 2024, que además es mi escritorio de trabajo diario con Arch Linux y Hyprland :

  • CPU: Intel i5-13500 (14 núcleos)
  • RAM: 32 GB DDR5
  • GPU: AMD Radeon RX 6600, que Immich y Ollama aprovechan vía ROCm
  • Disco: Kingston KC3000 de 2 TB NVMe (un solo disco, sin RAID)
  • Sistema: Arch Linux con Hyprland

Mucho tiempo tuve KDE de respaldo por si se complicaban las cosas, y también probé COSMIC en sus primeras versiones. Me gustó mucho.

Sobre el almacenamiento: he pensado montar un par de discos duros en RAID, pero no tengo mucho espacio físico y, sinceramente, tampoco la necesidad. La librería multimedia la tengo muy controlada: consigo lo que quiero ver, lo veo y lo borro.

El consumo eléctrico no lo he medido, lo tengo pendiente. Mi impresión es que el gasto depende más de cómo uses los servicios que de tenerlos levantados. Con los contenedores en reposo, la máquina apenas trabaja.

Un directorio por servicio

La estructura es tan simple como suena:

~/homelab/
├── traefik/
│   ├── docker-compose.yml
│   ├── traefik.yml
│   └── letsencrypt/
├── nextcloud/
├── immich/
├── jellyfin/
├── ollama/
├── openwebui/
├── searxng/
├── dawarich/
├── actualbudget/
├── beszel/
├── archived/
└── update-homelab.sh

Cada directorio tiene su docker-compose.yml con lo que necesita: la app, su base de datos, su Redis. No lo tengo en Git. Los servicios que he probado y he dejado de usar van a archived/, con su compose intacto por si algún día vuelvo.

Actualizaciones: latest y a rezar (pero con método)

Casi todo está en latest. Sé que no es lo ortodoxo, pero para un homelab personal me compensa.

La excepción son Nextcloud e Immich. Ahí sí leo las notas de versión antes de actualizar, porque son los que guardan mis datos y los que más cambios rompedores han tenido.

Para no ir directorio por directorio, tengo un script, update-homelab.sh, que recorre cada carpeta con un docker-compose.yml, hace pull, detecta si hay imágenes nuevas y solo entonces reinicia el servicio. Excluye archived/ y Nextcloud (que se actualiza desde su propio contenedor maestro), y deja Traefik para el final para no cortar el acceso al resto a mitad de proceso.

Los servicios que uso de verdad

Esta es la lista honesta. Lo que hago con cada uno, no lo que me gustaría hacer.

Traefik , el reverse proxy. Antes probé Caddy y después Nginx Proxy Manager, pero con Traefik es realmente sencillo: añado unas etiquetas al compose de cada servicio, el TLS se gestiona solo y listo. Solo expongo los puertos de cada contenedor a la red interna de Traefik en Docker, nunca al host. Lleva además el plugin Coraza como WAF, más por aprender que por necesidad, porque nada está expuesto a internet.

Nextcloud (instalación AIO), mi reemplazo de Google Drive y OneDrive. Lo uso a diario para sincronizar archivos entre Mac, Linux e iOS, incluida la bóveda de Obsidian.

Immich , en paralelo a iCloud como respaldo de fotos. No he dejado iCloud porque tengo una galería compartida con mi pareja de unas 37.000 fotos, y esa funcionalidad es complicada de replicar en Immich. Lo uso para deduplicar la biblioteca y buscar por personas. Me gusta su filosofía y sin duda acabaré dando el salto del todo.

Jellyfin . Empecé con Plex y lo cambié rápido. Alguna película o serie que no encuentro en plataformas, conectado a la tele en local, y poco más. No tengo suite arr: soy un usuario casual del contenido multimedia.

Ollama + Open WebUI , para hacer pinitos con modelos locales y conectar Ollama a otros contenedores. Con 8 GB de VRAM correr un modelo decente es complicado, y como tampoco programo mucho, no lo uso para autocompletar ni nada parecido.

SearXNG , el metabuscador. Lo tengo, lo trasteo de vez en cuando, pero la verdad es que no lo uso. La IA en las SERP y Perplexity son muy convenientes.

Dawarich , la alternativa a Google Timeline. Me gusta poder mirar atrás y ver dónde estuve qué día, y que esos datos no sean de nadie más. Lo uso para correlacionar transacciones y lugares. No necesita estar conectado al tailnet: va capturando puntos y luego sincroniza.

Actual Budget , contabilidad de andar por casa para los gastos mensuales.

Beszel , monitorización ligera de rendimiento, tanto de esta máquina como del VPS.

Y herramientas de marketing y SEO: Bisibility , en la que colaboro como tester y aportando ideas, y Elmo, pendiente de explorar.

En archived/ viven Baserow, Brewlog, Gitea, Homepage, LibreChat, Linkding, Pi-hole (la versión en Docker del post de macvlan ), Stirling PDF, Vane y Whoogle. Los probé, alguno lo usé una temporada, y los mantengo por si acaso.

El rabbit hole infinito

De vez en cuando caigo en la trampa de revisar algún “top apps para tu homelab”, un awesome docker compose o la configuración de otra persona, y casi caigo en querer hacer el deploy de todo. Luego nunca se usan.

Ese es el rabbit hole infinito del homelab. La mejor defensa que he encontrado es la lista de arriba: si no puedo decir en una frase para qué lo uso, va a archived/.

¿Cuánto consumen 40 contenedores?

Mucha gente quiere mantener la RAM al mínimo. Yo creo que la RAM está para usarla.

Ahora mismo tengo unos 40 contenedores levantados, contando bases de datos, Redis y demás piezas auxiliares. Entre todos consumen unos 8 GB de RAM de los 32 disponibles. Los que más piden son la búsqueda de texto completo y el antivirus de Nextcloud AIO (casi 3 GB entre los dos) y el servidor de Immich con su base de datos (1,5 GB). El resto son decenas de contenedores de entre 10 y 300 MB.

La CPU, en reposo, apenas se mueve. La mayoría de contenedores están por debajo del 1 %, y solo Immich y ClamAV pasan del 3 % cuando están procesando algo.

Hasta la fecha no me he tenido que preocupar de esto porque la máquina va holgada. Si tuvieras 8 o 16 GB, quitando la búsqueda de texto completo y ClamAV de Nextcloud, te cabría todo igual.

Y también un pequeño “cloudlab”

Aparte del homelab tengo un VPS sencillo en Hetzner con algunas cosas que sí necesitan estar públicas: Umami para la analítica de esta web, Uptime Kuma y alguna web estática en Hugo.

Me ha dado también mucha experiencia, porque ahí sí hay que pensar en exposición, firewall y hardening. Y, como no podía ser de otra manera, está dentro del mismo tailnet que el homelab.

Tailscale: acceder al homelab desde fuera sin abrir puertos

Aquí viene la mención especial. Tailscale me parece increíble, y es la pieza que hace que todo lo anterior tenga sentido con cero puertos abiertos en el router y ninguna máquina en DMZ.

¿Cómo accedo a mi homelab desde fuera sin abrir puertos?

Con una VPN mesh como Tailscale. Instalas el cliente en cada dispositivo, inicias sesión con tu cuenta y todos pasan a formar parte de una red privada (el tailnet) sobre WireGuard, sin tocar el router.

Cada dispositivo recibe una IP fija del rango 100.x.y.z y puede hablar con los demás estén donde estén. Nada de tu red local se expone a internet: desde fuera, tu IP pública no tiene ningún puerto escuchando.

Mi tailnet es pequeño: el PC con el homelab, el VPS de Hetzner, la máquina virtual con Pi-hole, el MacBook Air y el iPhone.

Diagrama del tailnet: homelab, VPS, MacBook, iPhone y Pi-hole conectados por Tailscale
Mi tailnet: cinco dispositivos, cero puertos abiertos

Por qué Tailscale y no WireGuard a pelo

Ya conté cómo configurar una VPN con WireGuard , y fue bien: rápido, implementación fácil. El problema fue mantener varios dispositivos.

Conectar a Hetzner desde Linux con unas claves y desde el Mac con otras era un poco caótico. Además, en aquella época usaba NordVPN (y después Mullvad), y era estar en una VPN o en la otra, con sus complicaciones.

Tailscale resolvió las dos cosas de golpe. Todos los dispositivos se ven entre sí sin gestionar pares ni claves a mano, y con su integración con Mullvad puedo usar un servidor de Mullvad como nodo de salida cuando quiero que mi tráfico salga por otro sitio.

No he probado Nebula, Headscale ni otras alternativas. La versión gratuita de Tailscale me da bastante más de lo que necesito.

Lo que uso de Tailscale (y lo que no)

  • MagicDNS: cada máquina responde por su nombre (ssh hetzy), sin acordarme de IPs.
  • Subnet router: para llegar a la red local de casa desde fuera cuando hace falta.
  • Nodos de salida: el de Mullvad, o salir desde una máquina concreta.
  • Taildrop: muy ocasional, para pasar un archivo entre el Mac y el PC.
  • Tailscale Serve: lo he usado una vez y bien.
  • ACLs, Funnel, SSH de Tailscale: no los uso.

Mi caso es simple: SSH entre mis máquinas y servir contenido del homelab al resto de dispositivos.

El truco: subdominios propios con TLS real dentro del tailnet

Esta es la parte que más me gusta del setup. Quería acceder a mis servicios como immich.midominio.net o nextcloud.midominio.net, con HTTPS de verdad y sin avisos del navegador, pero sin exponer nada a internet.

La solución tiene tres piezas:

  1. DNS público apuntando a una IP privada. En los registros DNS de mi dominio, el comodín *.midominio.net apunta a la IP de Tailscale de mi PC (100.x.y.z). Es un registro público, cualquiera puede consultarlo, pero esa IP solo es alcanzable desde dentro de mi tailnet. Fuera de él, no lleva a ningún sitio.
  2. Certificado wildcard por DNS challenge. Traefik pide a Let’s Encrypt un certificado para *.midominio.net usando el desafío DNS-01. En lugar de exponer un puerto 80 para que Let’s Encrypt lo verifique, Traefik crea un registro TXT temporal a través de la API de mi proveedor de DNS (Hetzner, en mi caso). Certificado válido, renovación automática, cero puertos.
  3. Traefik enruta por nombre de host. Cada servicio lleva una etiqueta en su compose del tipo traefik.http.routers.immich.rule=Host(`immich.midominio.net`), y Traefik lo sirve con el certificado wildcard.
Flujo DNS y TLS: el subdominio resuelve a la IP de tailnet, Traefik sirve el certificado wildcard obtenido por DNS challenge
DNS público, IP privada, certificado real: así funciona el acceso por subdominio

El resultado: desde el móvil activo Tailscale, abro immich.midominio.net y entro con candado verde, como si fuera un servicio público. Y desde fuera del tailnet, ese nombre no resuelve a nada útil.

Si te interesa un tutorial paso a paso de cómo tengo implementado esto (Traefik, DNS challenge y Tailscale), escríbeme por correo . Si hay interés, lo preparo.

Pi-hole solo para el tailnet

Tras un formateo dejé de usar el Pi-hole en Docker con macvlan del post anterior . Ahora tengo una pequeña máquina virtual con Pi-hole que actúa como DNS de todo el tailnet: cualquier dispositivo conectado a Tailscale resuelve a través de él, esté en casa o fuera.

Mi red local, en cambio, usa Quad9 (9.9.9.9) directamente. Es un compromiso: cuando estoy en una red que no controlo, activo Tailscale y mi resolución DNS pasa por mi propio Pi-hole. Tengo pendiente revisarlo y dejarlo de nuevo en Docker, o tener varios Pi-hole repartidos.

Desde el móvil

Lo uso poco, pero a demanda funciona genial. Activo Tailscale para entrar en Nextcloud o Immich, para que mi DNS pase por Pi-hole cuando estoy en una red insegura, o para salir desde un nodo concreto. Nada más.

Lo que no es tan bonito de Tailscale

Un poco de crítica, para que la recomendación tenga credibilidad:

  • Una vez me caducó la sesión de una máquina y no pude entrar en ella de forma remota. Tuve que ir a la consola y reautenticarla a mano. Si vas a depender de ello, revisa la caducidad de las claves de los nodos.
  • No es self-hosting puro. El plano de control (quién está en tu red, las claves de identidad) lo gestiona Tailscale. El tráfico va cifrado de extremo a extremo entre tus dispositivos y ellos no lo ven, pero dependes de un tercero para coordinar la red.

A mí me compensa la comodidad. Si tienes una necesidad concreta, siempre puedes configurar WireGuard a medida.

¿Merece la pena Tailscale?

Para un homelab personal, sí, sin duda. El plan gratuito cubre de sobra a un usuario con varios dispositivos, la configuración son cinco minutos por dispositivo, y a cambio te olvidas de abrir puertos, de DNS dinámicos y de gestionar claves de WireGuard a mano.

La principal contrapartida es depender de su plano de control. Si eso te incomoda, existe Headscale como alternativa autoalojada.

Podría incluso abrir algún nodo al público o dejarle una cuenta a mi pareja o a un familiar para que usara mis servicios. De momento, solo los uso yo.

Backups (o cómo Claude Code me ayudó con la parte aburrida)

Aquí es donde más me ha ayudado tener una IA al lado, porque es justo la parte que uno siempre deja para después.

Tengo Borg como repositorio de backups de los datos importantes. Ese repositorio lo vuelco a un disco físico externo que conecto de vez en cuando, y también a Filen , un almacenamiento cifrado en la nube. Copia local, copia externa y copia fuera de casa.

Homelab en la era de la IA

Hoy, un deploy es tan sencillo como decirle a Claude Code:

Quiero hacer el deploy de este repositorio de GitHub en mi homelab. Usa la configuración que tengo de Traefik, crea el directorio y lánzalo.

Y en diez minutos tengo algo funcionando para testear. Si me convence, voy haciendo arreglos yo solo. En 2024 esa misma tarea me costaba una tarde entera de leer documentación, un README a medias y tres hilos de Reddit.

¿Me ha configurado la IA algo “funcional” pero mal, a nivel de seguridad o permisos? No me ha pasado… o me ha pasado y no me he dado cuenta. Intento estar siempre del lado seguro al hacer los deploys, aunque reconozco que soy bastante menos paranoico que antes: estoy en mis equipos a diario, noto si algo va mal, y nada está expuesto a internet.

Mi consejo si empiezas hoy

Quien empieza hoy está en una situación curiosa. En su momento era leer mucha documentación, muchos posts de frikis como este, consultar Reddit y foros. Hoy la IA te resuelve, pero no te enseña. Pedirle expresamente que te enseñe es tedioso, y lo normal es que aceptes la solución y sigas.

Yo creo que las bases siguen siendo necesarias. Recuerdo que estuve una semana entera haciendo un tutorial gratuito de terminal (The Odin Project fue mi punto de partida) para aprender a manejar bash: cd, ls, mv, mkdir, grep. Nada espectacular, pero es lo que hace que hoy entienda lo que la IA me propone y pueda corregirlo.

El problema de fondo sigue siendo el mismo que antes: la paciencia. Tener la paciencia de leer y probar no cambia. Antes era el tutorial hell y ahora es la IA, que puede ser increíble pero también puede fomentar ansia y agobio por montar cosas que no entiendes.

Con quién aprendí

Si quieres empezar por donde empecé yo, estos son los canales con los que aprendí. Hace tiempo que no los sigo, y ahora hay muchos más creadores dedicados al homelab, pero siguen siendo una buena base:

Mención aparte para Alex, de KTZ Systems . Ha sido la voz de Tailscale durante estos años y es un gran comunicador. A fecha de escribir esta nota se está despidiendo de la empresa, y creo que muchos le hemos cogido cariño por el camino.

Y cuidado con NetworkChuck . Hace contenido muy consumible y mezcla didáctica con entretenimiento, pero hace que el hype se te vaya por las nubes. Consúmelo sabiendo lo que es.

Preguntas frecuentes

¿Es seguro Tailscale? ¿No te da miedo depender de una empresa para acceder a tu propia red?

Nada es seguro al cien por cien. Confío en Tailscale porque me dan buena sensación como empresa, por su política de privacidad y seguridad, y porque han sido transparentes todos estos años y han ido mejorando. El tráfico entre mis dispositivos va cifrado de extremo a extremo con WireGuard; lo que ellos gestionan es la coordinación de la red, no mis datos.

¿Qué pasa si Tailscale se cae o cierra? ¿Tienes plan B?

Buena pregunta, y no me lo había planteado hasta ahora. Probablemente tenga que implantar WireGuard como fallback para ese caso, o buscar algún mecanismo alternativo. Lo apunto como tarea pendiente.

¿Docker sobre Arch Linux en tu escritorio diario? ¿No es arriesgado mezclar homelab y máquina de trabajo?

Sí y no. Trabajo tanto en el Mac como en el desktop, así que no dependo de una sola máquina. Y el homelab son servicios que solo uso yo y que no están expuestos a internet, con lo que la superficie de ataque es mínima.

¿Por qué no Headscale, si te gusta el self-hosting?

Porque no lo conocía hasta ahora, y porque para las cosas más sensibles a veces prefiero confiar en profesionales. Por eso tampoco tengo mi propio gestor de contraseñas autoalojado.

¿Cómo compartes los servicios con tu pareja o familia si todo está detrás del tailnet?

No los comparto. Solo los uso yo. Con Tailscale sería fácil invitar a alguien a la red, pero de momento no hay necesidad.

¿Volverías a Proxmox si tuvieras una segunda máquina?

No. No le vi un sentido práctico en un entorno doméstico, salvo que quieras practicar virtualización por algún motivo concreto. Con Docker Compose y alguna máquina virtual puntual con virt-manager tengo todo lo que necesito.

¿Vas a publicar tus docker-compose.yml?

Lo tengo pendiente. Si este post tiene interés, subiré los compose sanitizados a un repositorio de GitHub. Mientras tanto, escríbeme si quieres alguno en concreto.

Conclusión

Si tuviera que resumir estos dos años y medio en una frase: menos es más. Un directorio por servicio, un reverse proxy, una VPN mesh y cero puertos abiertos.

Nada de esto impresiona en una captura de pantalla, pero funciona todos los días sin que tenga que tocarlo, y cuando quiero probar algo nuevo lo tengo levantado en diez minutos.

Y lo más importante: entiendo cada pieza. Eso es lo que el homelab me ha dado de verdad, y es lo que ninguna IA te va a dar si no pones la paciencia de aprenderlo.

Todos mis posts sobre el tema están en la etiqueta homelab . Si tienes dudas o quieres contar cómo tienes el tuyo, mándame un email.