Cloudflare Tunnels
Alternativa a Dominio y SSL con Let's Encrypt: en vez de abrir 80/443 en el droplet, el servidor abre una conexión saliente hacia Cloudflare y nunca expone puertos entrantes.
1. Qué es y por qué interesa
Un Cloudflare Tunnel crea un túnel cifrado saliente entre el servidor y Cloudflare. El tráfico público llega a Cloudflare y de ahí al servidor por el túnel — el servidor nunca abre un puerto hacia internet.
| Let's Encrypt + Traefik (actual) | Cloudflare Tunnel | |
|---|---|---|
| Puertos abiertos | 80, 443 | Ninguno — solo salida |
| Certificado | Traefik + Let's Encrypt (puede fallar/rate-limit) | Cloudflare hace el TLS — sin ACME |
| Protección DDoS | Ninguna | Sí, red de Cloudflare |
| Costo | Gratis | Gratis (plan free) |
| Requisito | IP pública + DNS | Dominio administrado por Cloudflare |
No sustituye el hardening pendiente (firewall, fail2ban) — es una capa adicional.
2. Requisitos
Dominio administrado por Cloudflare, Dokploy corriendo, y acceso al dashboard de Cloudflare.
⚠️ Al usar el túnel, hay que desactivar Let's Encrypt en Dokploy y usar HTTP (no HTTPS) en las conexiones internas — Cloudflare hace el TLS en su borde.
3. Crear el túnel
- Cloudflare Dashboard → Zero Trust.
- Networks → Connectors → Create a tunnel → conector Cloudflared.
- Nombrarlo (ej.
dokploy-tunnel) y copiar el Tunnel Token.
⚠️ El Tunnel Token permite enrutar tráfico al servidor — tratarlo como secreto.
4. Ajustar SSL/TLS en Cloudflare
En SSL/TLS, modo Full o Full (Strict).
⚠️ No usar "Flexible" — causa loops de redirección con Traefik.
5. Levantar cloudflared en Dokploy
- Nueva aplicación, Provider: Docker, imagen
cloudflare/cloudflared. - Environments →
TUNNEL_TOKEN="TOKEN-COPIADO". - Advanced → Arguments → dos entradas:
tunnelyrun. - Deploy — el contenedor debe quedar healthy.
6. Configurar los dominios públicos
Hay dos formas de decirle a Cloudflare qué dominios enruta:
Opción 1 — A través de Traefik (recomendado)
Flujo: Cloudflare → Tunnel → Traefik → tus apps. Un solo túnel sirve para todas las apps (con wildcard) y aprovecha la config de dominios ya hecha en Dokploy.
En el túnel → Configure → Published application routes → Add:
| Campo | Valor |
|---|---|
| Subdomain | ej. app |
| Domain | tu dominio |
| Service Type | HTTP |
| Service URL | dokploy-traefik:80 |
En la app de Dokploy, crear un dominio que coincida exactamente con el de Cloudflare, puerto 80, y sin activar HTTPS (entra en conflicto con el SSL de Cloudflare).
Opción 2 — Acceso directo al contenedor (sin Traefik)
Flujo: Cloudflare → Tunnel → tu app. Más simple para un solo servicio. Service URL como appName:port (ej. dokploy:3000).
⚠️ Con acceso directo, las configuraciones de dominio de Dokploy no aplican — cada contenedor se configura por separado en Cloudflare.
7. Wildcard (varias apps, un túnel)
- Copiar el Tunnel ID de Connectors.
- En DNS Records, crear CNAME: Name
*→ Contenttu-tunnel-id.cfargotunnel.com. - En Published application routes, agregar Subdomain
*, Service URLdokploy-traefik:80.
Un solo hostname cubre todas las apps — Traefik decide a cuál mandar según el dominio.
8. Cloudflare Access delante del panel
Si proteges el dashboard con Cloudflare Access, el login puede quedarse colgado aunque las credenciales sean correctas (con credenciales inválidas responde 401 de inmediato — despista).
Causa: Better Auth (auth de Dokploy) valida el header Origin. Si el origin no coincide con uno confiable, la request se descarta en silencio.
Configuración requerida:
BETTER_AUTH_SECRETestable (no debe cambiar entre reinicios, o se invalidan las sesiones):BETTER_AUTH_SECRET=$(openssl rand -hex 32)- Agregar el dominio a orígenes confiables:
BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000,https://dokploy.example.com - Settings → Server: Host = dominio público, HTTPS activado.
Tras los cambios, redeployar Dokploy para que las env vars surtan efecto. Si accedes por varios orígenes (dominio, IP interna, Tailscale), todos deben estar en
BETTER_AUTH_TRUSTED_ORIGINS.