Cloudflare Setup
3 min read
Cloudflare in front of a teploy app is entirely optional and set up on Cloudflare's side — teploy has no Cloudflare API integration. Your app works without it: SSL is handled automatically by Caddy via Let's Encrypt, and traffic goes straight to your server.
Why add Cloudflare?
- Global CDN — cache static assets at Cloudflare's edge
- DDoS protection — traffic filtering in front of your server
- Web Application Firewall — block common attacks before they reach Caddy
- Analytics — traffic insights at the edge
Set it up
This is configured entirely in Cloudflare's dashboard, not teploy's:
- Add your domain to Cloudflare and update your nameservers
- In Cloudflare DNS, point your A record at your server's IP and enable the proxy (orange cloud)
- In Cloudflare's SSL/TLS settings, choose a mode (see below)
teploy doesn't need to know Cloudflare is there — Caddy still serves the app the same way. The only teploy-side consideration is DNS validation: with the proxy enabled, your domain's A record resolves to a Cloudflare IP, not your server's, so teploy deploy's DNS check will fail unless you pass --skip-dns-check.
SSL modes
| Mode | Description |
|---|---|
| Full (Strict) | Cloudflare verifies your origin certificate — recommended |
| Full | Encrypts to origin, accepts self-signed |
| Flexible | Only encrypts browser to Cloudflare, plaintext to your server — avoid this |
With the proxy enabled, Caddy can no longer complete an HTTP-01 ACME challenge (Cloudflare, not your server, answers on port 80/443 from the public internet), so automatic Let's Encrypt HTTPS won't work for a proxied domain. Two options:
- Full (Strict), recommended: generate a Cloudflare Origin Certificate (Cloudflare's dashboard → SSL/TLS → Origin Server), then reference it from
teploy.yml:
teploy uploads these to the server on every deploy and Caddy terminates TLS with them instead of attempting ACME.tls: cert: ./certs/cloudflare-origin.pem key: ./certs/cloudflare-origin-key.pem - Cloudflare Tunnel: if you're using
cloudflaredinstead of a proxied A record, setingress: externalinteploy.yml— teploy skips Caddy routing entirely and your app is reachable at its Docker network alias, which the tunnel points to.
Without Cloudflare
If you don't put anything in front of your server:
- SSL is handled by Let's Encrypt (automatic, via Caddy)
- Traffic goes directly to your server
- No edge CDN caching
- DDoS protection is whatever your VPS provider offers at the network level
For most apps this is fine. Add Cloudflare later if you need CDN or edge-level filtering.