Sign inSign up

hapheus/cf-tunnel-sync

By hapheus

•Updated about 8 hours ago

Automated route and DNS synchronization between Docker containers and Cloudflare Tunnels

Image
Networking
Developer tools
0

7.5K

hapheus/cf-tunnel-sync repository overview

⁠🚀 Cloudflare Tunnel & Docker Sync

Docker Image Version Docker Pulls License: MIT

⚡ Headless by Design: hapheus/cf-tunnel-sync runs autonomously in the background without requiring any exposed ports or web server overhead.
📊 Need a GUI? Check out the optional companion container hapheus/cf-tunnel-dashboard⁠ for visual monitoring and live route diagnostics.

hapheus/cf-tunnel-sync automatically discovers Docker containers across your host and synchronizes Cloudflare Zero Trust Tunnel ingress rules and proxied DNS (CNAME) records in real time.


⁠✨ Features

  • 🔄 Real-Time Docker Discovery: Automatically provisions ingress rules and DNS records when containers start or stop.
  • 🎯 Fine-Grained Label Control: Configure custom hostnames, service protocols (http://, https://, tcp://), subpaths, and ports.
  • 🔒 Zero Trust & Access Integration: Attach Cloudflare Access service tokens and custom origin request configurations.
  • 🏢 Multi-Account & Multi-Tunnel: Route different compose stacks to distinct Cloudflare accounts and tunnels seamlessly.
  • 🛡️ Blast-Radius Protection & Deletion Guard: Automatically prevents bulk route teardown on engine restart with configurable limits (MAX_DELETIONS_PER_SYNC=3).
  • 🔍 Non-Mutating Preflight Validation: Validate Docker, tokens, and tunnels without mutations via --preflight or PREFLIGHT_ONLY=true.
  • 🔮 Predictive Dry-Run & ChangePlan API: Audit exact route mutations via --dry-run and GET /api/change-plan.
  • 🔬 6-Stage Truthful Diagnostics: Granular health checks ensuring zero false-positive sync reporting.
  • 📊 Status Dashboard & Web UI: Built-in dashboard with real-time stage status indicators.

💡 Quickstart: Looking for a fast walkthrough under 10 minutes? Check out the 10-Minute Canonical Quickstart Guide⁠.


⁠🚀 Quick Start with Docker Compose

Deploy the core gateway stack alongside cloudflared:

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel run
    environment:
      - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
    networks:
      - tunnel_net

  cf-tunnel-sync:
    image: hapheus/cf-tunnel-sync:latest
    container_name: cf-tunnel-sync
    restart: unless-stopped
    environment:
      - CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
      - CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID:-}
      - CLOUDFLARE_TUNNEL_NAME=${CLOUDFLARE_TUNNEL_NAME}
      - DOMAIN_NAME=${DOMAIN_NAME}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - tunnel_net

networks:
  tunnel_net:
    name: tunnel_net

⁠🏷️ Container Labels Reference

Enable any container for automatic synchronization by applying Docker labels:

LabelDescriptionExample
cf.tunnel.enableEnable tunnel synchronization (true or false).true
cf.tunnel.hostnameFully qualified domain name for public ingress.app.example.com
cf.tunnel.portTarget port inside the container (auto-detected if single port exposed).8080
cf.tunnel.serviceTarget service URL / protocol override.http://app:8080 or https://app:8443
cf.tunnel.pathOptional path prefix for path-based routing./api
cf.tunnel.originRequest.noTLSVerifyDisable TLS certificate verification for upstream.true
cf.tunnel.originRequest.httpHostHeaderCustom HTTP Host header sent to upstream service.backend.local
cf.tunnel.originRequest.originServerNameSNI hostname for upstream TLS handshake.backend.local
cf.tunnel.access.audCloudflare Access Application AUD tag for validation.<AUD_KEY>

⁠⚙️ Core Configuration Reference

VariableRequiredDefaultDescription
CLOUDFLARE_API_TOKENYesnoneCloudflare API Token with Account:Cloudflare Tunnel:Edit, Zone:DNS:Edit, and Zone:Zone:Read permissions.
CLOUDFLARE_ACCOUNT_IDNoauto-detectedCloudflare Account ID (auto-detected from domain zone or token if omitted).
CLOUDFLARE_TUNNEL_NAMEYes*noneName of the Cloudflare Zero Trust Tunnel (*or specify CLOUDFLARE_TUNNEL_ID).
CLOUDFLARE_TUNNEL_IDNoauto-detectedExplicit Cloudflare Tunnel UUID.
CLOUDFLARE_ZONE_IDNoauto-detectedExplicit Zone ID for the root domain.
DOMAIN_NAMEYesnoneRoot domain managed in Cloudflare (e.g. example.com).
POLL_INTERVALNo30Fallback polling interval in seconds for Docker state reconciliation.
SYNC_ON_STARTUPNotrueReconcile all existing running containers immediately on startup.
LOG_LEVELNoINFOLogging level (DEBUG, INFO, WARNING, ERROR).
DRY_RUNNofalseWhen true, plans and diffs changes without mutating Cloudflare.
PREFLIGHT_ONLYNofalseWhen true, executes read-only readiness checks and exits immediately without mutations.
MAX_DELETIONS_PER_SYNCNo3Maximum ingress/DNS route deletions permitted per sync cycle before safety guard aborts.
ALLOW_MASS_DELETIONSNofalseExplicit safety override to bypass blast-radius mass-deletion guard.
LOG_FORMATNotextLog format: text or json for structured observability.
CLOUDFLARE_MAX_RETRIESNo3Maximum retry attempts for transient Cloudflare API errors (429, 5xx).
NOTIFICATION_WEBHOOK_URLNononeWebhook URL for alerting on sync failures or blast-radius aborts.
NOTIFICATION_WEBHOOK_TYPENoautoWebhook format (auto, slack, discord, generic).
NOTIFICATION_COOLDOWN_SECONDSNo300Cooldown window in seconds suppressing duplicate alerts.
DOCKER_HOSTNounix:///var/run/docker.sockDocker daemon socket URI.
STATUS_PAGE_ENABLEDNotrueEnable internal API & status endpoint on port 8090.
STATUS_PAGE_PORTNo8090Internal status API listening port.
METRICS_ENABLEDNotrueExpose Prometheus metrics at /metrics.

⁠🖥️ Optional Web Dashboard Companion

cf-tunnel-sync performs all synchronization, self-healing, and preflight checks autonomously without needing a GUI.

If you would like a visual status dashboard, add the companion hapheus/cf-tunnel-dashboard⁠ container to your stack:

  cf-tunnel-dashboard:
    image: hapheus/cf-tunnel-dashboard:latest
    container_name: cf-tunnel-dashboard
    restart: unless-stopped
    ports:
      - "8090:80"
    environment:
      - DASHBOARD_AUTH_ENABLED=false # Set to true to require basic auth
    networks:
      - tunnel_net

Alternatively, you can publish port 8090:8090 directly on cf-tunnel-sync to access its internal status API and Prometheus metrics.


Tag summary

Content type

Image

Digest

sha256:3ba2ba033…

Size

25.7 MB

Last updated

about 8 hours ago

docker pull hapheus/cf-tunnel-sync