Docker + Cloudflare Tunnel: sin puertos, sin drama
Actualización (08/09/2026): Cambios y mejoras relevantes en Cloudflare Tunnel desde la publicación original.
- Alerta de deprecación: Cloudflare retira los endpoints legacy de Tunnel route y el campo connections el 5 de octubre de 2026; si usás Tunnel en Docker, verificá que tu configuración sea compatible con la nueva versión antes de esa fecha.
- Pre-checks de conectividad: Desde cloudflared 2026.5.2 el cliente incluye validaciones nativas de conectividad al levantar el servicio en Docker Compose, lo que facilita el troubleshooting cuando el túnel no arranca.
- Docker sin Nginx: Cloudflare Tunnel reemplaza completamente servicios como Nginx para enrutar tráfico entre contenedores sin exponer puertos públicos en la red interna.
- El plan Free sigue sin cambios: a septiembre de 2026 Cloudflare no anunció límites nuevos de transferencia ni de túneles para el plan gratuito; sigue siendo la opción sin costo para exponer contenedores Docker.
Actualizado el 08/09/2026 — Este artículo fue actualizado con información reciente y secciones nuevas.
En pocas palabras: exponer Docker con Cloudflare Tunnel y dominio personalizado te permite publicar un contenedor en internet mediante una conexión saliente encriptada, sin abrir puertos en el router, sin IP pública fija y con certificado HTTPS automático, usando el plan Free de Cloudflare.
Exponer Docker con Cloudflare Tunnel y dominio personalizado es hoy la forma más simple de publicar un contenedor en internet sin abrir puertos en el router. Cloudflare Tunnel es un servicio gratuito que crea una conexión saliente encriptada entre tu servidor local y la red edge de Cloudflare, sin necesidad de abrir puertos ni tener IP estática. Con esta guía podés tener la primera app publicada en menos de una hora, con HTTPS automático y cero puertos expuestos al mundo.
Cloudflare Tunnel es un producto de Cloudflare, la empresa de infraestructura web y seguridad, que conecta servicios Docker (u otro tipo de servidor) con internet sin exponer puertos ni la IP del origen. El cliente cloudflared corre dentro de un contenedor, abre una conexión saliente cifrada hacia el edge de Cloudflare, y esa conexión es la que recibe el tráfico HTTP/HTTPS dirigido a tu dominio.
En este artículo:
- En 30 segundos
- Por qué el port forwarding tradicional es inseguro
- ¿Qué es Cloudflare Tunnel y cómo funciona?
- ¿Cómo se encripta el tráfico entre tus contenedores y Cloudflare?
- Requisitos previos y configuración inicial
- Cómo exponer Docker con Cloudflare Tunnel: instalación de cloudflared
- ¿Cómo se configuran las reglas de ingress del túnel?
- Exponiendo tu aplicación con dominio personalizado
- ¿Cloudflare Tunnel es gratis?
- Cloudflare Tunnel vs. alternativas: la comparativa
- ¿Qué errores son más comunes al exponer Docker con Cloudflare Tunnel?
- Casos de uso y limitaciones reales
- Preguntas Frecuentes
- Conclusión
- Fuentes
En 30 segundos
- Reemplaza el port forwarding: Cloudflare Tunnel usa una conexión saliente encriptada, así que tu IP nunca queda expuesta ni hay puertos abiertos en el router.
- Es gratis: el servicio está incluido en el plan Free de Cloudflare y funciona con cualquier aplicación corriendo en Docker.
- Requisitos mínimos: una cuenta Cloudflare, un dominio con nameservers apuntados a Cloudflare, y tu app en contenedor.
- Configuración simple: un docker-compose.yml con el servicio cloudflared, más un config.yml con las reglas de ingress.
- El tráfico va encriptado: entre el navegador y Cloudflare por TLS, y entre Cloudflare y tu servidor por el túnel cifrado que arma cloudflared.
- Los errores más comunes: usar DNS interno de Docker en vez del nombre del servicio en la misma red, y redes Docker mal configuradas.
Cloudflare es una plataforma estadounidense de seguridad y rendimiento en la nube que proporciona servicios como CDN, protección contra ataques DDoS, firewall y DNS. Ofrece herramientas como Cloudflare Tunnel para conectar aplicaciones y servidores privados a internet de forma segura.
Por qué el port forwarding tradicional es inseguro
El port forwarding deja tu IP pública asociada a un servicio expuesto que cualquier scanner de internet puede detectar en minutos. Ponele que tenés una app Django corriendo en tu servidor casero y querés accederla desde afuera. La solución clásica: abrís el puerto 8000 (o el 80) en el router, configurás port forwarding hacia la IP local de tu máquina, y listo.
El problema aparece después. Herramientas como Shodan indexan millones de IPs con puertos abiertos todos los días. Si ese servicio tiene una vulnerabilidad (un panel de admin sin autenticación, un endpoint mal configurado, una versión desactualizada), el tiempo entre que el scanner lo detecta y que alguien lo explota puede ser de minutos.
La situación empeora si usás una IP dinámica, que es lo habitual en conexiones residenciales. Necesitás un servicio de DDNS, certificados SSL que renovar, reglas de firewall para cada servicio. La complejidad se apila rápido.
Cloudflare Tunnel resuelve esto invirtiendo la dirección de la conexión: en vez de que internet “entre” a tu servidor, es tu servidor el que “sale” hacia Cloudflare. Conexión saliente, sin puertos abiertos, sin exponer tu IP.
¿Qué es Cloudflare Tunnel y cómo funciona?
Cloudflare Tunnel es un proxy inverso gestionado por Cloudflare que conecta un servidor privado con internet sin abrir puertos entrantes. El cliente cloudflared corre en tu servidor, establece una conexión saliente encriptada con los servidores edge de Cloudflare usando el protocolo QUIC sobre UDP 7844, y a partir de ahí Cloudflare enruta el tráfico que llega a tu dominio hacia esa conexión, sin que nadie en internet necesite conocer tu IP real.
La diferencia con una VPN es importante. Una VPN conecta redes o dispositivos para acceso privado entre ellos. Cloudflare Tunnel conecta un servicio específico con internet de forma pública, pero sin exponer la infraestructura detrás. Para acceso a tu homelab desde vos mismo, una VPN puede ser mejor. Para publicar una app web para que otros la usen, el Tunnel es la opción. Relacionado: automatizar el despliegue con GitHub Actions de la misma app que después vas a exponer.
Todo esto es gratis en el plan Free de Cloudflare, sin límites de transferencia ni de túneles conocidos a la fecha.
¿Cómo se encripta el tráfico entre tus contenedores y Cloudflare?
El encriptado de contenedores en Cloudflare Tunnel funciona en dos tramos: TLS entre el navegador del usuario y el edge de Cloudflare, y una conexión cifrada por QUIC (o TCP 443 como fallback) entre el edge de Cloudflare y el cliente cloudflared que corre dentro de tu contenedor. En ningún momento el tráfico circula sin cifrar por internet.
Puertas adentro de tu red Docker, el tráfico entre cloudflared y el contenedor de tu aplicación (por ejemplo http://backend:8000) suele viajar sin TLS, porque se mueve dentro de una red bridge privada que no toca internet. Si necesitás cifrar también ese tramo interno —por ejemplo porque compartís el host con otros procesos que no son de confianza—, podés configurar el servicio interno con https:// en el config.yml y un certificado propio, aunque para la mayoría de los homelabs no es necesario.
Esto es distinto de encriptar el disco o los volúmenes del contenedor: Cloudflare Tunnel cifra el tráfico en tránsito, no los datos en reposo. Si tu aplicación maneja información sensible, el cifrado de volúmenes Docker es una capa aparte que tenés que resolver a nivel de sistema operativo o de tu proveedor de almacenamiento.
¿Cloudflare puede ver el contenido del tráfico que pasa por el túnel?
Sí: Cloudflare actúa como punto intermedio del tráfico HTTP/HTTPS que gestiona, igual que cualquier CDN o proxy inverso. Ve las requests que pasan por el túnel porque las procesa para aplicar reglas de enrutamiento, cache y seguridad. Para apps internas con datos muy sensibles, evaluá si ese nivel de visibilidad es aceptable antes de tunelizar el servicio.
Requisitos previos y configuración inicial
Antes de arrancar necesitás cuatro cosas en orden: una cuenta Cloudflare, un dominio con nameservers apuntando a Cloudflare, tu app en Docker, y conocimiento básico de terminal y docker-compose.
- Cuenta gratuita en Cloudflare: se crea en minutos y no pide tarjeta de crédito para el plan Free.
- Dominio con nameservers en Cloudflare: te dan dos nameservers propios, del estilo
xyz.ns.cloudflare.com, que reemplazás en tu registrador. - Tu aplicación corriendo dentro de Docker: no importa el stack (Django, Node, PHP), lo único que necesitás es que exponga un puerto HTTP dentro de la red Docker.
- Terminal y docker-compose básico: vas a editar un docker-compose.yml y, opcionalmente, un config.yml.
Para agregar el dominio a Cloudflare: entrás al dashboard, hacés clic en “Add a Site”, ingresás tu dominio y seleccionás el plan Free. Cloudflare escanea los registros DNS existentes automáticamente. Revisás, sacás los que no necesitás, y continuás. Luego vas a tu registrador (donde compraste el dominio) y reemplazás los nameservers actuales por los dos que te da Cloudflare.
Ojo con esto: si vas a usar Cloudflare Tunnel, no necesitás un registro A apuntando a tu IP de servidor. El tunnel crea automáticamente los registros CNAME necesarios. Si dejás un registro A viejo apuntando a tu IP, podés tener conflictos raros después.
Cómo exponer Docker con Cloudflare Tunnel: instalación de cloudflared
La forma más limpia de exponer Docker con Cloudflare Tunnel es agregar el cliente cloudflared como un servicio más dentro de tu docker-compose.yml existente, usando la imagen oficial cloudflare/cloudflared:latest.
Primero necesitás el token del túnel. Vas a Cloudflare Zero Trust (one.dash.cloudflare.com), navegás a Networks > Tunnels, creás un nuevo túnel con nombre descriptivo, y en la pantalla de configuración te muestra un token. Copiálo, lo vas a necesitar.
Tu docker-compose.yml queda algo así:
version: '3.8' services: cloudflared: image: cloudflare/cloudflared:latest restart: unless-stopped command: tunnel --no-autoupdate run environment: - TUNNEL_TOKEN=tu_token_aqui networks: - app_network backend: image: tu_imagen_django networks: - app_network frontend: image: tu_imagen_nginx networks: - app_network networks: app_network: driver: bridge
El restart: unless-stopped es importante para que el daemon del túnel se recupere solo si el contenedor se cae. Con cloudflared 2026.5.2 en adelante, además, el cliente corre validaciones de conectividad nativas al arrancar, así que un error de red aparece en los logs desde el primer segundo en vez de quedar en un estado ambiguo.
¿Cómo se configuran las reglas de ingress del túnel?
Las reglas de ingress se definen en el archivo config.yml del túnel, y determinan qué hostname va a qué servicio interno. Si usás el token directamente en la variable de entorno (como en el ejemplo anterior), Cloudflare toma la configuración desde el dashboard en Zero Trust. Si preferís un archivo local, montás el config.yml como volumen del contenedor.
Ejemplo de configuración con múltiples rutas:
tunnel: tu-tunnel-id credentials-file: /etc/cloudflared/creds.json ingress: - hostname: api.tudominio.com service: http://backend:8000 - hostname: tudominio.com service: http://frontend:80 - service: http_status:404
La última línea (http_status:404) es obligatoria: es el catch-all que maneja cualquier request que no matcheó ninguna regla anterior. Sin esa línea, el archivo config no es válido y el túnel no arranca.
Cuando hacés referencia a los servicios internos, usás el nombre del servicio Docker como hostname (como backend o frontend) siempre que estén en la misma red Docker. Si no, tenés que usar la IP del contenedor directamente, lo cual no es lo ideal. Organizá bien tus redes desde el principio.
Exponiendo tu aplicación con dominio personalizado
Con el túnel corriendo, vas a Zero Trust > Networks > Tunnels, seleccionás tu túnel, y en la pestaña “Public Hostname” agregás la ruta. Poné el subdominio o dominio raíz, seleccioná el tipo (HTTP/HTTPS), y ponés la dirección interna del servicio.
Cloudflare crea automáticamente el registro CNAME en el DNS de tu dominio apuntando al UUID del túnel. El HTTPS lo maneja Cloudflare en el edge, sin que vos tengás que configurar nada de Let’s Encrypt ni certificados. El tráfico entre el navegador y Cloudflare va encriptado; entre Cloudflare y tu servidor va por el túnel encriptado.
Según la guía publicada en mayo de 2026, el proceso completo para un stack React + Django + Nginx en Docker toma menos de una hora incluyendo la configuración del dominio.
¿Cloudflare Tunnel es gratis?
Sí, Cloudflare Tunnel es gratis: está incluido en el plan Free de Cloudflare, sin costo y sin límite de transferencia ni de túneles. No necesitás una tarjeta de crédito para activarlo ni hay una versión “trial” con vencimiento.
Lo que sí tiene costo son las funcionalidades avanzadas de Zero Trust que podés combinar con el túnel, como autenticación de usuarios por Access, políticas granulares o Browser Isolation. Esos planes arrancan desde USD 7 por usuario/mes. Para el caso de uso más común —publicar una app Docker con dominio propio y HTTPS automático— el plan Free alcanza y sobra.
La contracara de que sea gratis es que dependés de la disponibilidad de Cloudflare como intermediario: si el edge de Cloudflare tiene un incidente, tu app tunelizada también queda inaccesible, aunque tu servidor esté funcionando perfectamente.
Cloudflare Tunnel vs. alternativas: la comparativa
| Método | Puertos abiertos | IP expuesta | Costo | Complejidad | HTTPS automático |
|---|---|---|---|---|---|
| Port Forwarding | Sí | Sí | Gratis | Baja | No |
| VPN (WireGuard) | 1 puerto UDP | Sí | Gratis | Media | No |
| Cloudflare Tunnel | No | No | Gratis | Media | Sí |
| Ngrok (plan free) | No | No | Gratis/USD 10+ | Baja | Sí |
| Tailscale Funnel | No | No | Gratis/USD 6+ | Baja | Sí |
Para hosting de apps propias o acceso a un homelab desde afuera, Cloudflare Tunnel está en el podio. Según análisis comparativos de la comunidad homelabber en HomeLab Addiction, el túnel es la opción preferida cuando el objetivo es publicar servicios web sin comprometer la seguridad de la red local.
¿Qué errores son más comunes al exponer Docker con Cloudflare Tunnel?
Usar DNS interno de Docker en el config.yml (y no funciona)
El error más frecuente es poner service: http://mi-contenedor:8080 en el config.yml cuando cloudflared está en una red Docker distinta a la del contenedor objetivo, y por eso no puede resolver ese nombre. La solución es asegurarte de que todos los servicios estén en la misma red Docker (como en el ejemplo del docker-compose de arriba). Si no podés hacer eso por alguna razón, usá la IP del contenedor, que podés ver con docker inspect nombre_contenedor.
El YAML del config.yml no valida
El archivo config.yml falla al arrancar cuando la indentación tiene un tab en vez de espacios, o un espacio de más, porque YAML es estricto con eso. Antes de tirarte de los pelos, validá el YAML con cualquier herramienta online. Y acordate: la regla catch-all al final es obligatoria, no opcional.
Puerto UDP 7844 bloqueado por el firewall
Si tu proveedor de internet o firewall corporativo bloquea UDP saliente en el puerto 7844, el túnel no logra establecer la conexión con QUIC. La documentación oficial de Cloudflare indica que cloudflared cae automáticamente a TCP 443 en ese caso, pero si tampoco funciona, revisá las reglas de egress de tu firewall. En redes corporativas esto es más común de lo que parece.
El túnel arranca pero el dominio no resuelve
Cuando el contenedor está corriendo pero el dominio devuelve error, el primer paso es verificar tres cosas: que el CNAME se creó correctamente en el DNS de Cloudflare, que el túnel esté en estado “Healthy” en Zero Trust > Tunnels, y que la ruta del Public Hostname esté configurada. Los logs del contenedor cloudflared son tu mejor amigo acá: docker logs nombre_contenedor_cloudflared te muestra exactamente qué está pasando.
Si necesitás sacar tu Nextcloud a internet de forma segura, revisá cómo exponer tu app con Cloudflare Tunnel.
¿Qué pasa si mi configuración usa los endpoints legacy que Cloudflare retira el 5 de octubre de 2026?
Si tu túnel se creó hace tiempo con una versión vieja de cloudflared, revisá que no dependa de los endpoints legacy de Tunnel route ni del campo connections, porque Cloudflare los da de baja el 5 de octubre de 2026. La forma más simple de estar del lado seguro es actualizar la imagen a cloudflare/cloudflared:latest en tu docker-compose.yml y recrear el contenedor; la configuración basada en token y en Zero Trust dashboard (la que usa esta guía) no se ve afectada por esa deprecación.
Casos de uso y limitaciones reales
Cloudflare Tunnel tiene sentido para publicar apps de autoalojamiento, exponer herramientas de desarrollo para trabajo remoto, o publicar proyectos personales desde un servidor casero con IP dinámica, pero no reemplaza una VPN cuando necesitás acceso privado a toda una red.
- Autoalojamiento de aplicaciones: publicar herramientas como Nextcloud, Gitea o Planka sin depender de un VPS adicional.
- Acceso remoto a herramientas de desarrollo: exponer un entorno de staging o una herramienta interna para trabajo remoto sin VPN corporativa.
- Proyectos personales desde conexión domiciliaria: publicar un servidor casero con IP dinámica sin depender de DDNS.
- Streaming de alto ancho de banda: no es el mejor caso de uso, porque el tráfico pasa por los edge nodes de Cloudflare y eso agrega latencia adicional frente a una conexión directa.
- Apps que necesitan la IP real del cliente: reciben la IP del edge de Cloudflare, no la del usuario final, aunque Cloudflare pasa la IP original en el header
CF-Connecting-IP.
Si tenés un servidor en donweb.com y querés también tunelizar servicios locales de desarrollo hacia el mismo dominio, el Tunnel te lo permite con subdominios separados, sin tocar la configuración del servidor de producción.
Preguntas Frecuentes
¿Cloudflare Tunnel es mejor que abrir puertos en el router?
Para publicar aplicaciones web, sí: Cloudflare Tunnel no expone tu IP pública, no requiere puertos abiertos en el router, y te da HTTPS automático sin configuración extra. El port forwarding es más simple de entender pero deja tu servidor directamente expuesto a internet. Para juegos online o servicios que necesitan conexión directa (no HTTP/HTTPS), el port forwarding sigue siendo necesario porque el túnel solo maneja tráfico web.
¿Puedo usar Docker Compose con Cloudflare Tunnel?
Sí, y es la forma recomendada: agregás cloudflared como un servicio más en tu docker-compose.yml, pasás el token del túnel como variable de entorno, y lo ponés en la misma red Docker que tus otros contenedores. Así podés referenciar los otros servicios por nombre en las reglas de ingress. El token lo generás en Cloudflare Zero Trust al crear el túnel.
¿Cómo configuro Cloudflare Tunnel con múltiples subdominios?
En el archivo config.yml (o en el dashboard de Zero Trust > Tunnels > Public Hostnames) agregás una regla por subdominio, cada una con su hostname y servicio destino. Por ejemplo, api.tudominio.com puede apuntar al contenedor del backend en el puerto 8000, y tudominio.com al Nginx en el puerto 80. Cloudflare crea automáticamente un registro CNAME por cada hostname que configurás, sin que toques el DNS manualmente.
¿Cuánto cuesta Cloudflare Tunnel?
Cloudflare Tunnel no tiene costo dentro del plan Free de Cloudflare, sin límite de transferencia ni de túneles. Las funcionalidades avanzadas de Zero Trust (autenticación de usuarios, políticas de acceso, etc.) tienen planes pagos desde USD 7 por usuario/mes, pero para exponer aplicaciones públicas el plan Free es suficiente.
¿El tráfico de mis contenedores Docker queda encriptado con Cloudflare Tunnel?
Sí, el tráfico entre tu contenedor cloudflared y el edge de Cloudflare viaja cifrado por QUIC (o TCP 443 como respaldo), y el tramo entre el navegador del usuario y Cloudflare va por TLS estándar. Lo que no se encripta automáticamente es el tráfico interno entre contenedores dentro de tu propia red Docker, porque esa red ya es privada y no toca internet.
¿Qué hago si el túnel no conecta y los logs muestran errores de conexión?
Primero verificá que el puerto UDP 7844 saliente no esté bloqueado, porque cloudflared cae a TCP 443 automáticamente pero si también está bloqueado, la conexión falla. Después revisá que el token del túnel sea correcto y no tenga espacios extra al copiarlo. Si el túnel figura como “Degraded” en Zero Trust en vez de “Healthy”, revisá que el contenedor tenga acceso a internet con docker exec cloudflared ping 1.1.1.1.
Conclusión
El port forwarding tuvo su momento, pero para publicar aplicaciones Docker en 2026 hay opciones más seguras y sin la complejidad operativa de gestionar certificados, IPs dinámicas y reglas de firewall. Cloudflare Tunnel te da todo eso gratis: sin puertos abiertos, sin exponer tu IP, con HTTPS automático, con el tráfico encriptado en tránsito, y una configuración que entra en un docker-compose.yml de 20 líneas.
Si ya tenés Docker corriendo y un dominio en Cloudflare, podés tener la primera app publicada en menos de una hora; el paso que más tarda es la propagación de los nameservers, que puede demorar hasta 24 horas aunque generalmente es mucho menos. Para homelabs, desarrollo remoto o autoalojamiento, este setup ya no tiene excusas para no usarse. Y si preferís tercerizar el hosting del servidor que corre estos contenedores, en Donweb podés conseguir el dominio y la infraestructura de base para el mismo proyecto.
Fuentes
- Dev.to — How to Expose Your Docker App Securely with Cloudflare Tunnel (2026)
- Cloudflare Developers — Tunnel Troubleshooting (oficial)
- HomeLab Addiction — Cloudflare Tunnel vs VPN vs Port Forwarding
- CloudIngenium — Cloudflare Tunnels: exponer servicios de forma segura
- GitHub — container-cloudflare-tunnel (referencia de configuración Docker)
Ejemplo práctico: Home Assistant sin exposición directa
Martín tiene una Raspberry Pi 4 corriendo Docker en su casa de Villa Urquiza y quiere acceder a su panel de Home Assistant desde el laburo sin dejar puertos abiertos en el módem de Fibertel. Su dominio es casa-lopez.com.ar y ya tiene los nameservers apuntados a Cloudflare.
Arma un docker-compose.yml con el contenedor cloudflare/cloudflared:latest y lo monta en la misma red bridge que Home Assistant (172.17.0.2:8123). En el archivo config.yml define una única regla de ingress que mapea casa-lopez.com.ar a la IP interna del contenedor. Levanta el stack con docker compose up -d y, en menos de 90 segundos, el túnel aparece como “Healthy” en el dashboard de Cloudflare Zero Trust.
Resultado: Martín accede a su Home Assistant desde cualquier lado sin exponer el puerto 8123 en su router. Cloudflare le genera certificado SSL automáticamente y las 7 automatizaciones que tiene armadas —como la cámara del timbre y las luces del living— siguen funcionando sin cambios. Cero puertos abiertos, cero pesos gastados, y el tráfico entre su celular y la Raspberry va encriptado de punta a punta.





