Mi homelab Proxmox + Cloudflare Tunnel: stack y por qué
Cómo expongo proyectos públicos en internet desde mi servidor casero sin abrir un solo puerto en el router, sin pagar VPS, y con HTTPS automático.
Todo lo que ves en lalu.dev, oficina.lalu.dev, agents.lalu.dev, blog.lalu.dev, security.lalu.dev, ai.lalu.dev corre en una computadora bajo mi escritorio. Cero AWS, cero Vercel, cero Railway. Cuesta lo que cuesta la luz (~$5 USD/mes).
Esta es la receta exacta.
El hardware
Un mini-PC con:
- 4 cores · 8GB RAM · SSD 256GB
- Ubuntu Server (luego le metí Proxmox encima)
- Conexión doméstica detrás de un router cualquiera
Total: ~$300 USD comprado hace un año. Funciona.
La arquitectura
Internet
│
▼
Cloudflare (HTTPS, DDoS, WAF, cache)
│
▼ Cloudflare Tunnel (outbound-only, sin abrir puertos)
│
▼
[ VM Ubuntu en Proxmox ]
│
├── nginx ← entry point HTTP
├── Docker Compose ← 11+ containers
│ ├── portafolio (estático)
│ ├── blog (Astro estático)
│ ├── oficina-virtual (React)
│ ├── agents-discord (bot Python)
│ ├── ops-db (Postgres)
│ └── ...
└── otros servicios
Por qué Proxmox
Podría tener todo en una VM Ubuntu pelada. Pero Proxmox me da:
- Snapshots antes de hacer cambios riesgosos — un click y revierto
- Aislamiento por proyecto — si un proyecto se vuelve loco con la memoria, no se lleva al resto
- Backups automáticos programados
- Migración fácil si cambio de hardware mañana
Para self-hosting serio, vale la pena la capa extra. Para hobby — Docker directo en Ubuntu basta.
Por qué Cloudflare Tunnel (vs port forwarding)
Antes lo hacía con port forwarding clásico:
- Reenviar puerto 80/443 del router a la VM
- Caddy/nginx con Let’s Encrypt
- DNS apuntando a mi IP residencial
Funcionaba. Pero:
- Mi IP residencial pública estaba en el DNS — atacantes la encuentran, escanean puertos, intentan SSH brute-force, etc.
- Si el ISP cambia mi IP, todo cae hasta que actualizo DNS
- Si abro un puerto, tengo que mantener un firewall (UFW + fail2ban) actualizados
- El SSL me toca renovarlo (Caddy lo hace solo, pero igual es responsabilidad mía)
Cloudflare Tunnel cambia el modelo. La VM inicia una conexión saliente a Cloudflare. Cloudflare hace de proxy reverso. Nadie del internet conoce mi IP residencial. Nadie puede escanearme.
- Puertos abiertos en mi router: cero
- IP residencial pública: oculta
- HTTPS: automático, gestionado por Cloudflare
- Si mi IP cambia, no importa — el tunnel se reconecta solo
Es gratis, incluso para tráfico ilimitado. Cloudflare lo subsidia porque les da datos de tráfico web global.
El setup, paso a paso
1. Instalar cloudflared en la VM
curl -L --output cloudflared.deb \
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
2. Crear el tunnel en Cloudflare
En el dashboard de Zero Trust:
- Networks → Tunnels → Create a tunnel
- Le pones nombre (ej:
lalu-homelab) - Te da un comando con un token
3. Correrlo como container
Mi docker-compose.yml:
tunnel:
image: cloudflare/cloudflared:latest
restart: always
command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TOKEN}
El token está en .env (chmod 600). El container inicia la conexión a Cloudflare y se queda escuchando.
4. Mapear hostnames → servicios
En Tunnels → tu tunnel → Public Hostnames → Add a public hostname:
| Hostname | Service |
|---|---|
lalu.dev | http://nginx:80 |
blog.lalu.dev | http://blog:80 |
oficina.lalu.dev | http://oficina-virtual:80 |
agents.lalu.dev | http://agents-discord:8080 |
| … | … |
Cloudflare resuelve blog.lalu.dev → tu tunnel → tu container blog:80. Magia, pero entendible.
5. DNS automático
Cuando agregas un public hostname, Cloudflare crea automáticamente el CNAME en tu zona DNS. No tocas DNS a mano.
El SSL/HTTPS — gratis y automático
Cloudflare termina el HTTPS en su edge. Dentro del tunnel todo es HTTP plano (es túnel cifrado de extremo a extremo entre cloudflared y CF, así que no importa que sea HTTP en mi LAN). Yo no manejo certificados.
Si quieres HTTPS también dentro de tu LAN (defense-in-depth), puedes poner Caddy en medio. Para la mayoría de casos, sobra.
Lo que no me funcionó
Tailscale Funnel: similar concepto, pero más restringido (solo 3 hostnames free, sin custom domain en plan free). Para hobby, podría funcionar. Para vender servicios bajo tu dominio, no.
Ngrok: ideal para development, no para producción permanente. El plan free reasigna URLs.
Wireguard VPN + IP fija: te obliga a un VPS público, que es lo que querías evitar.
El truco del Zero Trust Access
Cloudflare Tunnel viene con un bonus: Access policies. Para mi /dashboard administrativo, agregué:
Application: agents.lalu.dev/dashboard Policy: Email is [email protected] Method: One-time PIN
Resultado: para acceder a mi dashboard interno, tengo que verificar mi email con un PIN. Sin VPN, sin password manager, sin que el endpoint sea públicamente accesible. Gratis hasta 50 usuarios.
El elefante en el cuarto: ¿qué pasa cuando se va la luz?
Tu homelab no tiene 99.9% uptime. Si se va la luz, todo cae.
Mis mitigaciones:
- UPS pequeño ($60 USD) — aguanta cortes cortos, da tiempo a shutdown ordenado
- BIOS “Restore on AC Power Loss: Power On” — cuando vuelve la luz, el host arranca solo
- Docker
restart: always— los containers se levantan con el host - VM autostart en Proxmox — la VM arranca con el host
Sin UPS, los cortes son inevitables. Si tu negocio depende de 24/7 garantizado, considera:
- VPS de respaldo en una región cualquiera ($5/mes)
- O migrar componentes críticos a Cloudflare Pages/Workers (gratis, edge)
- O ambos
Para freelance de proyectos puntuales — el self-hosting es perfectamente válido.
Costos reales del mes
| Concepto | Mes |
|---|---|
| Mini-PC (amortizado a 5 años) | ~$5 |
| Electricidad (~30W promedio) | ~$3 |
| Cloudflare (todos los servicios usados) | $0 |
| Dominios (4 a $12/año c/u) | $4 |
| Anthropic API (11 agentes) | ~$5 |
| Total | ~$17 USD |
Para comparar: Vercel Pro + Railway + Supabase + Anthropic + dominios = $100-200 USD/mes fácil.
Cuándo NO uses esto
- Si tu app necesita 99.99% uptime con SLA contractual
- Si esperas tráfico viral (millones de pageviews)
- Si tu cliente requiere SOC 2 / HIPAA / certificaciones formales
- Si tienes que escalar horizontalmente bajo demanda
Para todo lo demás — portafolios, blogs, MVPs, side-projects, herramientas internas, proyectos freelance — self-hosting con Proxmox + Cloudflare Tunnel es óptimo.
Si quieres ver el sistema funcionando, todo lo que está en lalu.dev corre exactamente en este setup. Los stats live de oficina.lalu.dev vienen de esta misma máquina.