I often run one Caddy in front of a whole app. It reverse-proxies to the other components, so the Caddyfile belongs in the project.
Development, staging, and production each need their own Caddyfile. Sometimes I need a personal one too, with my own hostnames. They can’t all be named Caddyfile or they collide in git.
I keep a caddy directory at the root of the repo. Git tracks a file per environment. It ignores the plain Caddyfile. On each machine I symlink the right file into place.
caddy/
Caddyfile -> Caddyfile.development
Caddyfile.development
Caddyfile.staging
Caddyfile.production
Caddyfile.ryan
.gitignore has:
caddy/Caddyfile
On a development machine:
cd caddy
ln -sf Caddyfile.development Caddyfile
On production, same command, different target:
ln -sf Caddyfile.production Caddyfile
Caddy always reads Caddyfile. From the project root, the command never changes:
caddy run --config caddy/Caddyfile
Scripts and systemd units point at that same file, so they don’t need to know which environment they’re on. After a clone, make the symlink before you run Caddy.
That’s the whole trick.