caddy run: Start Caddy in the Foreground
caddy run starts the server in the foreground and blocks, which is exactly what containers and CI test harnesses want.
Unlike caddy start (which daemonizes), caddy run stays in the foreground so a container or a CI step can supervise it and capture logs directly.
What it does
caddy run loads the config, adapts it if needed, provisions modules, binds the configured addresses, and runs until it receives a termination signal. It logs to stderr as structured JSON by default. Because it does not fork, it is the correct entrypoint for Docker and for background-and-smoke-test patterns in CI.
Common usage
caddy run --config Caddyfile --adapter caddyfile
# reload config while running by re-reading on change
caddy run --config Caddyfile --watch
# background it for a smoke test, then curl
caddy run --config Caddyfile &
curl -fsS http://localhost:2019/config/ >/dev/nullOptions
| Flag | What it does |
|---|---|
| --config <file> | Config file to load |
| --adapter <name> | Config adapter (e.g. caddyfile) |
| --watch | Reload automatically when the config file changes |
| --environ | Print the environment before running (debugging) |
| --resume | Use the last autosaved config instead of --config |
In CI
Use caddy run (not caddy start) as a container CMD so signals and logs flow correctly. For a smoke test, background caddy run, poll the admin API at http://localhost:2019/config/ or your site, then send SIGTERM. Validate the config with caddy validate before running to fail fast.
Common errors in CI
run: loading initial config: loading new config: ... means the config failed to load; the tail of the message names the cause. "listen tcp :80: bind: address already in use" means the port is taken. "loading config file: open Caddyfile: no such file or directory" means a wrong --config path. Automatic HTTPS can fail in CI with ACME errors; set the site to http:// or use auto_https off for local tests.