Caddy reload is not enough
I edited my Caddyfile, ran caddy reload, and nothing changed. The config was
valid. The reload succeeded. Caddy still served the old config.
The setup
Caddy runs in Docker. The compose file bind-mounts one file, not a directory:
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
The cause
A bind mount of a single file attaches to the file’s inode, not to its
name. Many tools do not edit a file in place. They write a new file and rename
it over the old one. GNU sed -i does this, and so do many editors.
After such an edit:
- On the host, the name
Caddyfilepoints to a new inode with the new config. - In the container, the mount still points to the old inode with the old config.
caddy reload reads /etc/caddy/Caddyfile inside the container. It gets the
old file, finds it valid, and reloads the same config.
How to see it
Compare the inode before and after an edit:
stat -c %i Caddyfile
sed -i 's/foo/bar/' Caddyfile
stat -c %i Caddyfile # a different number
Or diff the two views directly:
diff Caddyfile <(docker exec caddy cat /etc/caddy/Caddyfile)
The fixes
Pick one:
- Restart the container after an edit that replaces the file. A restart mounts the current inode. This drops connections for a moment.
- Edit in place. Appending with
>>or writing withcat > filekeeps the inode. Check withstatif you are not sure. - Mount the directory, not the file. Then the container sees the new
name after a rename, and a plain
caddy reloadworks.
Option 3 is the real fix. I use option 2 for now, and I check the inode before and after each edit.