TutorialsJune 6, 20263 min read

Set up Caddy for automatic HTTPS on a VPS

Caddy is a modern web server that gets you free HTTPS with zero configuration. Learn to install it and serve a site or reverse-proxy an app with automatic SSL.

NBy Nxeon

Caddy is a modern web server whose headline feature is automatic HTTPS. Point it at a domain and it obtains, installs and renews a Let's Encrypt certificate for you โ€” no Certbot, no manual config. For many projects it's the fastest path from VPS to secure website.

Why Caddy

  • HTTPS by default โ€” TLS certificates are fetched and renewed automatically.
  • Tiny config โ€” the Caddyfile is often just a few lines.
  • Great reverse proxy โ€” perfect for putting HTTPS in front of a Node.js, Python or Go app.
  • Single binary โ€” no sprawling dependency tree.

Step 1: Install Caddy

On Ubuntu or Debian, add the official repository and install:

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
sudo apt update
sudo apt install caddy -y

Caddy installs as a systemd service and starts immediately. Confirm it's running:

systemctl status caddy

Step 2: Open the firewall

Caddy needs ports 80 and 443 โ€” 80 is used for the certificate challenge and redirects:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Step 3: Point your domain at the server

Create an A record for your domain pointing at the VPS IP. Caddy can only get a certificate once the domain resolves to the server.

Step 4: Serve a static site

Caddy is configured by /etc/caddy/Caddyfile. To serve files with automatic HTTPS, replace its contents with:

example.com {
    root * /var/www/example.com
    file_server
}

Create the site and reload:

sudo mkdir -p /var/www/example.com
echo "<h1>Served by Caddy over HTTPS</h1>" | sudo tee /var/www/example.com/index.html
sudo systemctl reload caddy

Visit https://example.com โ€” Caddy has already fetched a certificate. That's the whole thing: name the domain, and HTTPS just happens.

Step 5: Reverse-proxy an app

The most common real use is putting Caddy in front of an app running on a local port. Say your Node.js app listens on port 3000:

app.example.com {
    reverse_proxy localhost:3000
}

Reload:

sudo systemctl reload caddy

Now https://app.example.com securely proxies to your app, with TLS terminated by Caddy. This is dramatically simpler than the equivalent Nginx-plus-Certbot setup.

Handy Caddyfile patterns

Multiple sites โ€” just stack blocks:

site-a.com {
    reverse_proxy localhost:3000
}

site-b.com {
    root * /var/www/site-b
    file_server
}

Gzip/zstd compression:

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

Validate before reloading

Check your Caddyfile for errors:

caddy validate --config /etc/caddy/Caddyfile

Caddy vs Nginx

Nginx is the veteran with more tuning knobs and a bigger ecosystem โ€” reach for it on complex, high-traffic setups. Caddy wins on simplicity and automatic TLS, which makes it ideal for small-to-medium sites, side projects, and quickly fronting an app with HTTPS. On a Nxeon VPS with full root you can install either; if your goal is "secure site, minimum fuss," Caddy gets you there in about five minutes.

#caddy#https#web-server#reverse-proxy#vps

Deploy your first server in under a minute

No credit card required to get started. Spin up a VPS, break things, and only pay for what you keep running.