This article applies to both Debian 10 Buster and Ubuntu 20.04 Focal.

What is Caddy?

Caddy is an open source web server that is simple in design, easy to use and has many powerful features. It can handle TLS (SSL) automatically and can use middleware extensions.

Caddy uses a simple configuration syntax to easily configure routing, reverse proxies, redirects, caching and other features. It also supports HTTP/2, QUIC (HTTP/3) and WebSockets protocols to provide fast web performance.

Why try Caddy?

The simple reason for me was that the nginx-quic project was never released and I wanted a simple web server software that supported HTTP/3 and Caddy was the right choice for me at the moment.

Caddy also supports automated certificates, which is especially good for lazy people.

Installing Caddy

We follow the official installation method and first, install some necessary packages.

1
2
3
apt update
apt upgrade -y
apt install curl vim wget gnupg dpkg apt-transport-https lsb-release ca-certificates

Then add Caddy’s GPG public key and apt source.

1
2
curl -sSL https://dl.cloudsmith.io/public/caddy/stable/gpg.key | gpg --dearmor > /usr/share/keyrings/caddy.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/caddy.gpg] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main" > /etc/apt/sources.list.d/docker.list

You can then update your system and install Caddy.

1
2
apt update
apt install caddy

Configuring Caddy

The default Caddyfile file is located at /etc/caddy/Caddyfile, the official tutorial is available here, if you are used to Nginx and Apache configuration then you should be very uncomfortable at this point, so let’s take the simplest example.

  1. we need to bind the domain name example.com.
  2. the file for this domain is located at /var/www/example.com and the default home page file name is index.html.
  3. we need to turn on SSL and automatically redirect http to https.
  4. we need to set up TLS 1.2 and TLS 1.3 to be enabled, and HSTS Preload to be enabled.

First, set http://example.com/ to redirect to https://example.com/.

1
2
3
example.com:80 {
    redir https://{host}{uri} permanent
}

We then write Caddyfile in accordance with Mozilla’s recommended configuration.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
example.com:443 {
    tls {
        protocols tls1.2 tls1.3
        ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
    }

    header {
        Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
        Referrer-Policy strict-origin-when-cross-origin
        X-Frame-Options SAMEORIGIN
        X-Content-Type-Options nosniff
        X-XSS-Protection "1; mode=block"
    }

    root * /var/www/example.com

    file_server {
        index index.html
    }

    encode gzip zstd
}

Of course you can also set www.example.com to redirect to example.com.

1
2
3
4
5
6
7
www.example.com:80 {
    redir https://example.com{uri} permanent
}

www.example.com:443 {
    redir https://example.com{uri} permanent
}

Then combine all the above into a Caddyfile file. Put it in /etc/caddy/Caddyfile and check the Caddy configuration.

1
caddy validate --config /etc/caddy/Caddyfile

The following output indicates correct configuration.

1
2
3
4
5
6
7
root@debian ~ # caddy validate --config /etc/caddy/Caddyfile
2022/12/26 17:31:22.347	INFO	using provided configuration	{"config_file": "/etc/caddy/Caddyfile", "config_adapter": ""}
2022/12/26 17:31:22.349	WARN	http	server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server	{"server_name": "srv1", "http_port": 80}
2022/12/26 17:31:22.349	INFO	http	enabling automatic HTTP->HTTPS redirects	{"server_name": "srv0"}
2022/12/26 17:31:22.349	INFO	tls.cache.maintenance	started background certificate maintenance	{"cache": "0xc00018ad90"}
2022/12/26 17:31:22.350	INFO	tls.cache.maintenance	stopped background certificate maintenance	{"cache": "0xc00018ad90"}
Valid configuration

For the OCD, you can also spruce up your Caddyfile.

1
caddy fmt --config /etc/caddy/Caddyfile --overwrite

Finally, restart Caddy.

1
systemctl restart caddy

After waiting patiently for the SSL certificate to be issued automatically, we can then open our browser console and look at https://example.com/ to see that the SSL certificate has been deployed automatically and that HTTP/3 is on.

The SSL certificate has been automatically deployed and HTTP/3 has been turned on.