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.

NXNxeonStraight-talking guides from the team that runs the servers4 min read
Quick answer

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.

Topic
Tutorials
Read time
4 min read
Covers
caddy, https, tls
Last updated
August 5, 2026

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:

terminalbash
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:

terminalbash
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.

terminalbash
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:

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

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

terminalbash
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.

Reverse proxy in two lines

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

code
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:

terminalbash
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:

code
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:

code
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:

terminalbash
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.

Put this guide to work on Cloud VPS hosting. From $8.88 for the first term, then $12.78 a month.

NX
Nxeon

Nxeon editorial · Straight-talking guides from the team that runs the servers.

Deploy in seconds, not weekends.

Full root access on NVMe cloud VPS with instant deployment — the flexible way to host anything.