Synchronize Docker container labels with Cloudflare Tunnel ingress and proxied DNS CNAME records. The Python controller manages configuration; the separate cloudflared connector carries traffic to applications on a reachable Docker network.
Give a running application a hostname and its internal port, then attach it to the connector's network:
services:
web:
image: nginx:alpine
networks:
- cf-tunnel-net
labels:
cf.tunnel.hostname: web.example.com
cf.tunnel.port: "80"
networks:
cf-tunnel-net:
external: trueThe gateway discovers the service through Docker events and periodic reconciliation, updates its named tunnel, and manages the corresponding CNAME. The default fallback interval is 900 seconds; events use a 2.5-second debounce window. No application host-port mapping is required for tunnel traffic.
The controller can initialize a tunnel, write the connector token to a shared volume, and attempt a connector restart. It exposes status, logs, metrics, and an embedded dashboard. A separate Nginx dashboard is optional; headless deployments do not need published API ports.
Use a dedicated tunnel and a scoped token. Ownership comments, grace periods, and deletion limits reduce accidental cleanup, but current behavior has important boundaries:
- Dry-run performs reads and planning only: it does not create a tunnel, write its token, or restart the connector. A missing tunnel is reported as a prerequisite.
- Manual ingress paths, duplicate rules, catch-alls, and their relative order are preserved. The first root route for an actively discovered hostname is managed by the synchronizer.
- Missing, empty, or null DNS comments do not establish ownership. The default policy can adopt matching untagged records for active services.
- Access labels are status metadata and do not configure authentication.
Read architecture and safety and security before connecting an existing deployment. Use --preflight for non-mutating inspection; it still reads configured Docker and Cloudflare resources.
| Example | Purpose |
|---|---|
| Single stack | Gateway, connector, and demo application together. |
| Separate stacks | One gateway network shared by independent application stacks. |
| Socket proxy | Restrict Docker API access; automatic restart is blocked. |
| Origin settings | HTTPS origins, custom headers, and explicit port selection. |
| Multiple gateways | Separate domains, tokens, connector targets, and volumes. |
The root Compose file publishes the embedded dashboard on host port 8080 and enables authentication by default. The Quickstart uses a headless gateway instead. See configuration before changing ports or environment values.
| Desktop | Mobile |
|---|---|
![]() |
![]() |
Screenshots illustrate the UI; status reflects controller observations rather than an independent end-to-end application health check.
MIT.

