Operate Caddy

Run Caddy as a service

Use the official system service, dedicated account, configuration paths, and journal instead of an improvised background process.

caddy run in a terminal dies with your SSH session. A real server needs Caddy supervised: started at boot, restarted after a crash, logging somewhere durable. On Linux that supervisor is systemd, and the official package already set it up for you.

See what got installed

Two commands show you the service:

systemctl status caddy
systemctl cat caddy

status shows whether Caddy is running, since when, and its most recent log lines. cat prints the unit file itself.

Read that unit file once. It answers most questions about how Caddy runs: as the caddy user, loading /etc/caddy/Caddyfile, restarting on failure. Notice the ExecReload line too. It means systemctl reload caddy maps to Caddy’s graceful reload, so configuration changes don’t need a restart.

Read the logs

Logs go to the journal:

journalctl -u caddy --since today
journalctl -u caddy -f

The first command shows today’s runtime log: startup, certificate activity, errors. The second follows it live. Keep that one open in a second terminal whenever you change configuration. You’ll see problems the moment they happen.

The service user

The service user matters more than people expect. caddy is an unprivileged account. The unit grants it just enough capability to bind ports 80 and 443. It can read /etc/caddy, and it writes its own state under /var/lib/caddy. It cannot read your home directory.

That’s the number one source of “it works with caddy run but not as a service”. You tested as your own user, and the service user can’t reach your files.

Fix permission problems narrowly. Move site files somewhere sensible like /srv/www, make them readable by the caddy group, and confirm with the service user’s own eyes:

sudo -u caddy ls /srv/www

If that lists your files, Caddy can read them. If it says permission denied, you found the problem before touching the Caddyfile.

Don’t chmod 777 a directory tree to make an error go away. You’d be trading a visible failure for an invisible one.

Skip caddy start on servers

Caddy has its own backgrounding command, caddy start. My advice is to never use it on a server. It leaves a process that nothing supervises. If it crashes at 3am, nobody restarts it, and you find out from a user.

The systemd service gives you boot integration, a restart policy, and one obvious place to look when something breaks. Use it, and use systemctl to manage it.

Lesson completed