This episode guides you through installing Caddy via various methods: official package managers, binary downloads, Docker, and building from source. You'll also run a first run, check the logs, and verify that the installation works correctly.

Episode 0 already showed a quick repository installation. Episode 3 expands that into a complete guide: all of Caddy's installation methods, how to manage the systemd service, running a first run, and verifying that everything works. Choose the method that best fits your environment.
Caddy can be installed many ways — package manager, binary download, Docker, even building from source. Each method has trade-offs: the package manager is the easiest for updates, Docker is the cleanest for container deployment, and building from source is required when you want to add plugins via xcaddy (episode 29).
After installation, we'll make sure Caddy runs as a service and that its logs are readable. This verification matters so debugging in later episodes doesn't start from scratch.
The recommended way on Linux is the official repository. On Debian and Ubuntu:
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddyFor RedHat, CentOS, and Fedora, run the rpm variant:
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/rpm.repo.txt' | sudo tee /etc/yum.repos.d/caddy-stable.repo
sudo dnf install caddyThe package manager installation also creates the caddy user and a systemd service file. Caddy will start automatically and try to open ports 80 and 443.
Because the package installer sets up a service, you can manage it like any other Linux service:
sudo systemctl enable caddy
sudo systemctl start caddy
sudo systemctl status caddyThe sudo systemctl status caddy command shows the service status, PID, and recent logs. This is the most convenient way to make sure Caddy runs in the background.
If you're not using a supported distro, download the binary directly from the official Caddy download page:
curl -o caddy.tar.gz 'https://caddyserver.com/api/download?os=linux&arch=amd64'
tar xzf caddy.tar.gz
sudo mv caddy /usr/local/bin/
caddy versionThe downloaded binary is a standard build. If you need extra plugins, use xcaddy — we cover that in episode 29. Make sure the architecture matches: use arch=arm64 for ARM servers.
Without a package manager, you can run Caddy directly:
caddy run --config /etc/caddy/CaddyfileForeground mode (caddy run) is great for debugging because all logs appear in the terminal. For production without systemd, use caddy start, which runs Caddy in the background.
The official caddy image is available on Docker Hub and the Caddy registry. The simplest example:
docker run -d -p 80:80 -p 443:443 \
--name caddy \
-v $PWD/Caddyfile:/etc/caddy/Caddyfile \
-v $PWD/site:/srv \
-v caddy_data:/data \
caddy:2Volume mount breakdown:
Caddyfile:/etc/caddy/Caddyfile — the configuration file.site:/srv — the site content.caddy_data:/data — certificates and storage (must be persistent!).docker run -d -p 80:80 -p 443:443 caddy:2 maps the HTTP and HTTPS ports to the container. Docker details will be dissected in episode 27.
Check that the image and container are running:
docker ps
docker logs caddydocker logs caddy shows Caddy's logs from inside the container — this is the main debugging path when Caddy runs in Docker.
Once Caddy is installed, create a basic Caddyfile and run it:
localhost:8080 {
respond "Caddy installation successful!"
}Then run and test:
caddy run --config Caddyfile
curl -i http://localhost:8080A 200 OK response with the body Caddy installation successful! means the installation works. Use curl -i to see the response headers — a detail you'll use often when debugging.
Caddy's logs contain information about config loading and errors:
sudo journalctl -u caddy --no-pagerThe sudo journalctl -u caddy command reads the systemd service logs. If Caddy runs in the foreground, the logs appear directly in the terminal. Always look for the serving initial configuration line — the sign that Caddy loaded the Caddyfile successfully.
If ports 80 or 443 are already taken by another web server, Caddy will fail to bind. Solutions: stop the other service, or change the ports in the Caddyfile. Check port usage with ss -tlnp or netstat -tlnp.
Caddy needs read access to the Caddyfile and content directories. Make sure the caddy user (if using systemd) has sufficient permissions. Check with ls -l on the relevant files and directories.
Episode 3 walked you through installing Caddy via the official package manager, binary download, Docker, and even building from source — plus systemd service management, a first run, and log verification. You now have a running, monitorable Caddy.
Key takeaways:
caddy user and a systemd service.caddy_data volume in Docker must be persistent to store certificates.curl -i and journalctl -u caddy are your main verification tools.In the next episode, episode 4, we'll cover Caddyfile fundamentals — syntax, comments, indentation, environment variables, site block variations, essential directives like root, file_server, respond, and reverse_proxy, plus global options. This is core material you'll use in every episode that follows.