A minimal Caddy build with Cloudflare DNS support for automated HTTPS certificates.
126
Docker image for Caddy with the Cloudflare DNS provider included.
This image is useful when Caddy needs to issue TLS certificates with the DNS-01 ACME challenge through Cloudflare. DNS-01 validation works well for servers that are not directly reachable from the public internet, wildcard certificates, and reverse proxy deployments behind Cloudflare.
/data and /config volumesdocker pull ghcr.io/bbaskovc/docker-image-caddy-cloudflare:latest
Use a fixed tag in production when available:
docker pull ghcr.io/bbaskovc/docker-image-caddy-cloudflare:<tag>
Create a Cloudflare API token with permission to edit DNS records for the zone you want Caddy to manage.
Create compose.yaml:
services:
caddy:
image: ghcr.io/bbaskovc/docker-image-caddy-cloudflare:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
environment:
CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./site:/srv:ro
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
Create .env:
CLOUDFLARE_API_TOKEN=replace-with-your-cloudflare-api-token
Create Caddyfile:
{
acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
example.com {
root * /srv
file_server
encode zstd gzip
}
Start Caddy:
docker compose up -d
{
acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
app.example.com {
reverse_proxy app:8080
encode zstd gzip
}
When the upstream service is another Docker container, put both containers on the same Docker network and use the service name as the upstream host.
If you only want Cloudflare DNS validation for selected sites, configure it in the site block:
example.com {
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
reverse_proxy app:8080
}
Create a Cloudflare API token with the minimum permissions required for DNS validation:
Zone / Zone / ReadZone / DNS / EditLimit the token to the specific zone used by Caddy whenever possible.
Do not commit the token to Git. Pass it through an environment variable, Docker secret, or your deployment platform's secret manager.
Caddy stores certificates, account data, and runtime state in /data.
Keep this volume persistent so certificates survive container recreations.
Caddy stores autosaved configuration and related config state in /config.
Persisting this volume is recommended for normal Docker deployments.
docker build -t docker-image-caddy-cloudflare .
Run the locally built image:
docker run --rm \
-p 80:80 \
-p 443:443 \
-p 443:443/udp \
-e CLOUDFLARE_API_TOKEN=replace-with-your-cloudflare-api-token \
-v "$PWD/Caddyfile:/etc/caddy/Caddyfile:ro" \
-v caddy_data:/data \
-v caddy_config:/config \
docker-image-caddy-cloudflare
Check that the Cloudflare DNS module is present:
docker run --rm ghcr.io/bbaskovc/docker-image-caddy-cloudflare:latest caddy list-modules | grep cloudflare
Expected module:
dns.providers.cloudflare
80 and 443 are
not publicly reachable, but Caddy still needs reachable ports to serve normal
HTTP and HTTPS traffic./data persistent to avoid unnecessary certificate re-issuance.See the repository license for details.
Content type
Image
Digest
sha256:a6f6f14ec…
Size
39.3 MB
Last updated
4 months ago
docker pull bbaskovc/caddy-cloudflare