The Caddy web server is a modern, extremely powerful, and easy-to-use web server written in Go. Its standout feature is built-in automatic HTTPS support (via Let’s Encrypt), which works out of the box without manual SSL certificate issuance and renewal via Certbot.
In this guide, we will look at how to install Caddy on Linux distributions (using Ubuntu/Debian as an example), configure its configuration file (Caddyfile), and launch the service.
1. Installing Caddy on Linux (Ubuntu / Debian)
The recommended installation method is using the official developer repository. This ensures you get the up-to-date version with all security updates.
Run the following commands in your terminal:
# 1. Install necessary dependencies
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# 2. Add the official Caddy repository GPG key
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# 3. Add the official Caddy repository
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
# 4. Update package lists and install Caddy
sudo apt update
sudo apt install caddy
Managing the Systemd Service
After installation completes, Caddy automatically starts as a system service. You can manage it using standard systemctl commands:
# Check service status
sudo systemctl status caddy
# Restart Caddy
sudo systemctl restart caddy
# Stop Caddy
sudo systemctl stop caddy
# Enable automatic startup on system boot
sudo systemctl enable caddy
2. Configuration Structure (Caddyfile)
The main configuration file is the Caddyfile, which is typically located at /etc/caddy/Caddyfile.
The Caddyfile syntax is extremely concise and avoids excessive curly braces when parameters are on separate lines.
Example of a Basic Configuration File:
example.com {
# Site root directory
root * /var/www/html
# Enable file server / static file serving
file_server
# Response compression (gzip, zstd)
encode gzip zstd
# Request logging
log {
output file /var/log/caddy/example.com.log
}
}
3. Setting Up a Static Website
Create a directory for your website:
sudo mkdir -p /var/www/htmlCreate a simple test page
index.html:sudo nano /var/www/html/index.htmlAdd the following code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Caddy is working!</title> </head> <body> <h1>Hello, World! Caddy web server successfully configured.</h1> </body> </html>Set the correct file owner permissions (so the
caddyuser has access to the site):sudo chown -R caddy:caddy /var/www/html
4. Reverse Proxy
One of the most common tasks for Caddy is proxying requests to local applications (e.g., Node.js, Python, Docker containers).
Example Caddyfile configuration for proxying requests to an application running on port 3000:
app.example.com {
reverse_proxy localhost:3000
}
If the application runs inside Docker on the same host, you can specify the container name or internal port:
app.example.com {
reverse_proxy 127.0.0.1:8080
}
Caddy will automatically issue an SSL certificate for app.example.com and initiate a secure (HTTPS) connection with the client, forwarding requests to the backend over plain HTTP.
5. Validating and Applying Configuration
After making changes to /etc/caddy/Caddyfile, always check the configuration for syntax errors:
sudo caddy validate --config /etc/caddy/Caddyfile
If validation succeeds, reload the configuration without stopping the web server itself (graceful reload):
sudo systemctl reload caddy
Conclusion
We have successfully installed the Caddy web server on Linux, created a basic site structure, set up static content serving, and configured a reverse proxy. Thanks to automatic TLS certificate management, Caddy spares the administrator from routine Certbot maintenance, making administration fast, reliable, and secure.