TutorialsAugust 4, 20264 min read

How to Install Caddy and Get Automatic HTTPS

Caddy is a modern web server that fetches and renews TLS certificates for you. Install it on Ubuntu 24.04 and serve HTTPS with a two-line config.

NBy Nxeon

Caddy is a web server that does one magical thing out of the box: it gets and renews HTTPS certificates automatically, with no Certbot and no cron jobs. Point a domain at your server, write two lines of config, and you have a valid TLS certificate. This guide installs Caddy on Ubuntu 24.04 and shows both static-site and reverse-proxy setups.

Why Caddy?

With Nginx or Apache you install the server, then install Certbot, then set up renewal. Caddy folds all of that into the server itself: on first request for a domain it talks to Let's Encrypt, provisions a certificate, and keeps it renewed silently. For small teams and hobby projects this removes a whole category of "my certificate expired" incidents. If you would rather use the classic stack, see installing Nginx instead.

Install from the official repository

Caddy publishes an apt repository. Add it 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. Check it:

systemctl status caddy

Open the firewall and DNS

Automatic HTTPS needs ports 80 and 443 reachable from the internet, and your domain's A record must already point at the server. If it does not, follow how to point a domain to your VPS first.

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

The Caddyfile

Caddy's config lives at /etc/caddy/Caddyfile. To serve a static site with automatic HTTPS, this is the entire config:

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

Create the web root, add a page, and reload:

sudo mkdir -p /var/www/example.com
echo '<h1>Caddy on Nxeon</h1>' | sudo tee /var/www/example.com/index.html
sudo systemctl reload caddy

The first time you load https://example.com, Caddy provisions a certificate on the fly. No extra commands.

The Nxeon game-server control panel — live console, player slots, and TPS
The Nxeon game-server control panel — live console, player slots, and TPS

Reverse proxy in two lines

Running an app on a local port? Caddy makes proxying trivial — and it still handles TLS automatically:

app.example.com {
    reverse_proxy 127.0.0.1:3000
}

That is the whole config. Compare this to the equivalent Nginx reverse proxy setup — Caddy trades fine-grained control for radical simplicity, and it forwards the standard X-Forwarded-* headers by default.

Validate and reload safely

Always format and validate before reloading:

caddy fmt --overwrite /etc/caddy/Caddyfile
caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

Where the certificates live

Caddy stores certificates and keys under /var/lib/caddy/.local/share/caddy. You never touch these directly, but it is reassuring to know renewal is handled there automatically, roughly a third of the way through each certificate's lifetime.

Serve several sites and add headers

Caddy scales to many domains as cleanly as one — each site is its own block in the Caddyfile:

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

blog.example.com {
    reverse_proxy 127.0.0.1:2368
}

Every domain gets its own automatic certificate. You can attach response headers inline, too:

example.com {
    root * /var/www/example.com
    file_server
    header {
        X-Content-Type-Options nosniff
        Referrer-Policy strict-origin-when-cross-origin
    }
}

Read Caddy's logs

Because Caddy runs as a systemd service, its output goes to the journal:

sudo journalctl -u caddy -f

That is where certificate provisioning and any config problems appear — the first place to look if a site does not come up. Add a per-site log directive when you need request-level access logs.

FAQ

Does Caddy really renew certificates with no cron job?

Yes. Renewal is built into the running server; it checks certificates in the background and renews well before expiry. There is nothing to schedule and nothing to forget.

Can I use Caddy for local development without a public domain?

Yes. Use localhost or a .localhost name in your Caddyfile and Caddy issues a locally-trusted certificate via its internal CA — handy for testing HTTPS-only features.

How does Caddy compare to Nginx on performance?

For most workloads the difference is negligible; both are fast. Nginx has an edge in very high-concurrency static serving and a larger ecosystem of third-party modules. Caddy wins decisively on setup simplicity and automatic TLS.

What if port 80 is blocked and I still need a certificate?

Caddy can use the TLS-ALPN challenge on port 443 or the DNS challenge with a provider plugin, so it can still issue certificates when port 80 is unavailable.

Nxeon VPS plans give you a clean Ubuntu 24.04 base with full root, so you can install Caddy and have HTTPS live in a couple of minutes — and free migration help if you are moving a site across.

#caddy#https#tls#ubuntu#web server#seobatch

Deploy your first server in under a minute

Creating an account is free and takes no card details. You pay when you deploy — choose a billing term and pay from your wallet or by card at checkout.