Auto reload Caddyfile in Caddy docker compose
Caddy supports --watching and automatically reloading the Caddyfile but unfortunately, this isn’t enabled in various docker images.
This means you need to refresh (or poke the docker container) everytime you change the “Caddyfile”.
Thankfully, docker allows you to overwrite the ENTRYPOINT defined in the running docker container with your own command.
The ENTRYPOINT is defined in the existing Dockerfile as “CMD [“caddy”, “run”, “—config”, “/etc/caddy/Caddyfile”, “—adapter”, “caddyfile”]” so to reproduce the existing behaviour and get automatic reloading of Caddy file add the following to the caddy service in your “docker-compose.yaml” (the existing ENTRYPOINT and the new “—watch” argument):
command:
[
"caddy",
"run",
"--config",
"/etc/caddy/Caddyfile",
"--adapter",
"caddyfile",
"--watch",
]
As an example, assume the following “compose.yaml”:
services:
caddy:
container_name: caddy
image: ghcr.io/caddybuilds/caddy-cloudflare:latest
command:
[
"caddy",
"run",
"--config",
"/etc/caddy/Caddyfile",
"--adapter",
"caddyfile",
"--watch",
]
restart: no
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy-config:/config
- ./caddy-data:/data
- ./Caddyfile:/etc/caddy/Caddyfile
with the following “Caddyfile”:
localhost {
respond "Hello, world"
}
docker compose up in the directory containing the “compose.yaml”:
➜ caddy docker compose up
[+] Running 1/1
✔ Container caddy Running 0.0s
Attaching to caddy
Viewing (with a browser or curl, whatever):
➜ caddy curl --insecure https://localhost
Hello, world%
Change the HTML returned by the “Caddyfile”:
localhost {
respond "Hello, world - wootage!"
}
and you should see your log (in the terminal you ran docker compose up) reload the file:
caddy | {"level":"info","ts":1765042844.273521,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
Visit the page again and rejoice:
➜ caddy curl --insecure https://localhost
Hello, world - wootage!%
Wootage.