Problem
Adding a domain in Coolify leaves another configuration task: adding its hostname to a remotely managed Cloudflare Tunnel. Repeating that work by hand can leave the two systems out of sync.
Approach
A small Python container polls the Coolify and Cloudflare APIs, compares app domains with tunnel routes, and adds missing hostnames. It preserves existing routes, skips hosts already covered by wildcard rules and keeps the catch-all 404 rule last. Optional DNS sync creates CNAME records.
Dry-run mode logs proposed changes before writes are enabled. The GitHub Actions workflow runs pytest before the container build and GHCR publish job; pull requests run tests without publishing an image.
Coolify app domains ─┐
├→ compare → dry-run log / add missing routes
tunnel config ──────┘ │
optional DNS CNAMEsTradeoffs
- Additive reconciliation protects existing routes but leaves removal of stale routes to the operator.
- Polling is simple to operate, with a delay between an app change and a tunnel update.
- API tokens need narrowly scoped permissions; DNS writes are optional.
Outcome
A public MIT-licensed automation tool with dry-run support, tests and a container publishing workflow. The reconciler encodes route-preservation rules instead of replacing the whole tunnel configuration from app data.