Self-hosting en un mini PC con Docker + Cloudflare Tunnel
Cómo publicar varios servicios web de forma segura con un solo mini PC en casa. HTTPS con Cloudflare Tunnel sin abrir puertos, y todo funcionando con Docker Compose.
Lo esencial
Levantas los servicios con Docker Compose en un mini PC y les conectas dominio y HTTPS con Cloudflare Tunnel (cloudflared) sin abrir puertos. No necesitas configurar el router, ni IP fija, ni renovar certificados.
En esta página
Las facturas de la nube pesan más de lo que parece en los proyectos pequeños. Yo tengo este blog y varios servicios más corriendo en un solo mini PC en casa. Aquí comparto cómo.
Por qué un mini PC
- Está siempre encendido y la electricidad cuesta unas pocas monedas al mes
- Con Docker, el entorno de despliegue es idéntico al de la nube
- Si el tráfico crece, ya migrarás entonces
El único problema es este: "¿cómo expongo mi red doméstica al exterior de forma segura?".
No abras puertos
La forma tradicional es port forwarding en el router + DDNS + renovación de certificados. Es engorroso y, además, equivale a abrir tu red doméstica directamente a internet: peligroso.
En su lugar usamos Cloudflare Tunnel. En el mini PC, cloudflared abre una conexión hacia afuera en dirección a Cloudflare, y el tráfico entra por ese túnel. Los puertos de entrada abiertos hacia el exterior son 0.
사용자 → Cloudflare(HTTPS) → 터널 → 미니 PC 의 컨테이너
- No necesitas IP pública ni port forwarding
- Cloudflare gestiona automáticamente el certificado HTTPS
- Da igual que tu IP sea dinámica
Agrupar los servicios con Docker Compose
Cada servicio corre en un contenedor. Si es una app de Next.js, la compilas con output: "standalone" para generar una imagen ligera.
services:
blog:
build:
context: .
dockerfile: apps/blog/Dockerfile
container_name: why-next-blog
restart: unless-stopped
networks: [api]
networks:
api:
external: true # cloudflared 와 같은 네트워크
La clave es ponerlos en la misma red de Docker que cloudflared. Así el túnel puede encontrar cada servicio por el nombre de su contenedor.
Conectar el dominio
En el dashboard de Cloudflare (o en la configuración del túnel) añades un Public Hostname.
blog.example.com → http://why-next-blog:3001
Y eso es todo. Ejecutas docker compose up -d --build y unos minutos después el sitio se abre en tu dominio.
En resumen
- Mini PC + Docker = despliegue barato e idéntico al de la nube
- Dominio y HTTPS sin abrir puertos gracias a Cloudflare Tunnel
- Contenedores en la misma red que cloudflared
- Mapeo
dominio → contenedor:puertocon Public Hostname
Para servicios pequeños, esta combinación aguanta muchísimo tiempo. Yo mismo tengo varias apps corriendo así, y sigo ampliando las cosas que he creado.
Preguntas frecuentes
Mi IP de casa es dinámica, ¿hay problema?
Ninguno. Con Cloudflare Tunnel es el mini PC el que abre la conexión saliente hacia Cloudflare, así que no necesitas IP pública, ni port forwarding, ni DDNS.
¿Tiene algún costo?
Cloudflare Tunnel en sí es gratuito. Solo necesitas pagar el dominio para empezar.
Artículos relacionados
- 💻 Desarrollo
Cuando un bucket tiene dos dueños, gana el último que hace apply
Añadí una sola regla de lifecycle en S3 y terraform apply falló. La causa: una estructura en la que dos recursos poseían cada uno por su cuenta la configuración de lifecycle del mismo bucket. El lifecycle de S3 no opera por reglas sino por documento entero, así que el último ganador borra en silencio las reglas del otro.
- 💻 Desarrollo
Los tests estaban en verde, pero la notificación nunca llegó a enviarse
El código que encolaba el job fallaba desde el primer día, siempre. El error se tragaba en un catch y los tests seguían en verde gracias a los mocks. La historia de cómo un solo carácter, dos puntos, mató en silencio tres funcionalidades.
- 💻 Desarrollo
Llegó una alerta diciendo que la base de datos estaba caída. La base de datos nunca se cayó
En un solo día se acumularon cuatro alertas CRITICAL. Un 504, un P2028 de Prisma, un 500 en el admin y 'servicio DATABASE caído'. Abrí primero las métricas de RDS y durante 21 horas seguidas la CPU no pasó del 19.7%, tan tranquila. Lo lento no era la base de datos, sino un viaje de ida y vuelta que cruzaba el Atlántico veinticinco veces, y la alerta de 'caída' se la había fabricado el propio health check.