Automated route and DNS synchronization between Docker containers and Cloudflare Tunnels
10K+
hapheus/cf-tunnel-sync reads Docker labels and manages Cloudflare Tunnel ingress and CNAME records. Run it alongside cloudflared, which carries application traffic. The embedded dashboard is optional; headless deployments still run the internal API without publishing a host port.
Follow the complete QUICKSTART.md for the gateway Compose file. Both services must mount the same token volume at /etc/cloudflared; the connector runs with --token-file /etc/cloudflared/token. Do not supply a manually copied connector token as a substitute for that setup.
Attach your service to the connector's Docker network and use a single fully qualified hostname and explicit internal port:
labels:
cf.tunnel.hostname: app.example.com
cf.tunnel.port: "8080"
Current discovery does not use cf.tunnel.enable to opt in or out. Path labels are not wired into normal routing, and Access labels are metadata rather than access controls. Use the maintained label reference for actual spellings and behavior.
Set CLOUDFLARE_API_TOKEN, DOMAIN_NAME, and a dedicated CLOUDFLARE_TUNNEL_NAME. Account selection is normally derived from the zone. The fallback sync interval is 900 seconds; Docker events trigger earlier runs.
MAX_DELETIONS_PER_SYNC defaults to three and ALLOW_MASS_DELETIONS overrides execution deletion limits. LOG_FORMAT=json enables structured logs; NOTIFICATION_WEBHOOK_URL enables alert delivery. Pass these into the container explicitly; a Compose .env entry alone is not automatically injected.
For read-only inspection, run python app.py --preflight or set PREFLIGHT_ONLY=true. It reads configured Docker and Cloudflare resources and exits. DRY_RUN=true also blocks tunnel creation, token-file writes, connector restarts, and ingress/DNS mutations. If the tunnel is missing, it reports that provisioning is required.
The configuration reference distinguishes active settings from names only recognized by validation or other entry points.
The internal HTTP port is 8090. Keep it private unless deliberately publishing it with authentication. The embedded dashboard and optional hapheus/cf-tunnel-dashboard use the documented API.
Use a scoped Cloudflare token and treat Docker socket access as privileged even with a :ro mount. Manual ingress rules and absent DNS ownership fields have known safety limitations. Use a dedicated tunnel rather than assuming existing routing is preserved losslessly.
Content type
Image
Digest
sha256:ef1969f23…
Size
28 MB
Last updated
about 12 hours ago
docker pull hapheus/cf-tunnel-sync