I think I found the problem. If I perform a rebuild, I never restart Caddy. From now on, I’m going to do this:
./launcher rebuild app && systemctl reload caddy
I suspect that Caddy uses the socket cache or something similar after a rebuild. But it doesn’t usually happen immediately after a rebuild. We’ll see.