Tips, DevOps, Linux, Server

Tip: Effortless HTTPS with Caddy Web Server

By One Dot Lab Team

Setting up a web server often involves a tedious dance: install Nginx or Apache, configure virtual hosts, install Certbot, generate Let's Encrypt certificates, and set up cron jobs for renewal.

Caddy changes the game completely. It is a modern, open-source web server written in Go that handles HTTPS automatically and by default.

Why Use Caddy?

  1. Automatic HTTPS: Caddy automatically obtains and renews TLS certificates for your sites (via Let's Encrypt or ZeroSSL). No extra steps required.
  2. Simple Configuration: The Caddyfile syntax is incredibly human-readable compared to Nginx or Apache configs.
  3. Production Ready: It supports HTTP/3, compression, and robust reverse proxying out of the box.

Prerequisites

  • A Linux server (Ubuntu/Debian used in examples).
  • Root or sudo access (required for installation and binding to ports 80/443).
  • A domain name (e.g., example.com) pointing to your server's IP address.

Step 1: Install Caddy

These commands work for Debian, Ubuntu, and Raspbian. For other distributions, check the official docs.

First, install the necessary dependencies and add the official Caddy repository key:

bash
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

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

Now, update your package list and install Caddy:

bash
sudo apt update
sudo apt install caddy

Once installed, Caddy starts automatically as a systemd service. You can check its status:

bash
systemctl status caddy

Step 2: Configure Caddy

Caddy is configured using a file located at /etc/caddy/Caddyfile.

Open it with your favorite editor (requires sudo):

bash
sudo nano /etc/caddy/Caddyfile

Example A: Reverse Proxy (Node.js, Python, Go)

This is the most common use case. If you have an app running on localhost:3000, your Caddyfile should look like this:

Caddyfile
example.com {
  reverse_proxy localhost:3000
}

That is literally it. Caddy will see the domain name, automatically fetch an SSL certificate, and proxy traffic to port 3000.

Example B: Static File Server

If you just want to serve HTML/CSS/JS files from a directory:

Caddyfile
example.com {
  root * /var/www/html
  file_server
  encode gzip
}

Step 3: Reload and Test

After saving your Caddyfile, apply the changes without downtime:

bash
sudo systemctl reload caddy

Verification

  1. Open your browser and visit https://example.com.
  2. You should see the lock icon indicating a secure connection.
  3. You didn't have to run Certbot or manage keys manually!

Troubleshooting

If something isn't working, check the logs:

bash
journalctl -u caddy --no-pager | tail -n 20

Or validate your configuration file for errors before reloading:

bash
caddy validate --config /etc/caddy/Caddyfile

Conclusion

Caddy removes the friction of managing web servers and security certificates. For most modern deployments, especially on simple VPS instances, it is the most efficient choice.