Set up a DNS challenge with Cloudflare
By default, Companion Hubβs Traefik obtains TLS certificates with an HTTP challenge. That path needs your machine reachable from the internet on port 80. A DNS challenge with Cloudflare lets Traefik request trusted certificates from Letβs Encrypt without opening anything to the internet.
You canβt complete this setup in the current release. A DNS challenge
needs two changes that Hub doesnβt keep: a Cloudflare API token passed to the
traefik container, and a dnsChallenge resolver in traefik.yml. Hub
rewrites state/traefik/config/traefik.yml every time the Hub container
starts, the Persist Traefik config setting doesnβt stop that, and a
user-config/hub-compose.yml override isnβt applied when you start the stack
with cihub up. See Customize compose and
Traefik.
How it works
Instead of Letβs Encrypt calling in to your machine over HTTP, Traefik proves ownership by writing a challenge record into your Cloudflare zone with an API token. Nothing in the exchange needs your Hub reachable from the internet.
sequenceDiagram
participant T as Traefik on your Hub
participant LE as Let's Encrypt
participant CF as Cloudflare DNS
T->>LE: Request a certificate for your domain
LE-->>T: DNS challenge to prove ownership
T->>CF: Write the challenge record (CF_DNS_API_TOKEN)
T->>LE: Ready to verify
LE->>CF: Look up the challenge record
CF-->>LE: Record found
LE-->>T: Certificate issued
Note over T: Stored in /etc/traefik/acme.json| HTTP challenge (default) | DNS challenge | |
|---|---|---|
| Port 80 reachable from the internet | Required | β |
| Domain managed in Cloudflare | β | β |
| Cloudflare API token passed to Traefik | β | β |
| Resolver in traefik.yml | httpChallenge, entryPoint: web | dnsChallenge, provider: cloudflare |
| Supported by Hub today | Yes, the default | No |
The default resolver is named myresolver, and Traefik stores its certificates in /etc/traefik/acme.json inside the container, which Hub mounts from state/traefik/acme_storage.json in your data root.
What to use instead
Pick the option that matches who needs to reach your apps:
- Trusted HTTPS on the public internet β expose the app through the Cloudflare Gateway. Cloudflare terminates TLS, so you need no certificate and no open port.
- Trusted HTTPS for your own devices β use Tailscale. Enable HTTPS certificates for your tailnet in the Tailscale admin console.
- HTTPS on your LAN only β use the Hubβs self-signed certificate and trust it on your devices. See Local SSL certificate.
- Your own domain β add it as a custom domain in your CI Account. Forwarding ports 80 and 443 to the Hub for a Letβs Encrypt certificate is no longer supported on production Hubs; see Expose your apps.