For a recent project, I wanted to move to Caddy Server v2 and have support for wildcard domains. This required me to setup a DNS provider in order for Lets Encrypt to validate that I own the domain to then provide a wildcard certificate.

Because the DNS plugins aren’t built into the main Caddy executable, you need to compile it with the plugins you want installed.

Here’s the steps I used to compile and install Caddy.

1. Install Go

wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.16.3.linux-amd64.tar.gz

# Add this to your .profile, .bashrc or .bash_profile
# then logout & login
export PATH=$PATH:/usr/local/go/bin

go version

2. Install xcaddy

xcaddy is a tool for building custom packages of Caddy

sudo apt update && sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | sudo apt-key add -
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list
sudo apt update && sudo apt install xcaddy

3. Build Caddy with the CloudFlare DNS Plugin

This will compile Caddy with the DNS plugin

xcaddy build --with github.com/caddy-dns/cloudflare

4. Move the caddy executable

sudo mv caddy /usr/bin/

caddy version

5. Create a user

sudo groupadd --system caddy
sudo useradd --system \
    --gid caddy \
    --create-home \
    --home-dir /var/lib/caddy \
    --shell /usr/sbin/nologin \
    --comment "Caddy web server" \
    caddy

6. Create a systemd service

sudo nano /etc/systemd/system/caddy.service

And paste the contents of this, editing as required:

# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

7. Create a Caddyfile

Place a Caddyfile at /etc/caddy/Caddyfile with the DNS setting

*.mysite.com {
  reverse_proxy 127.0.0.1:1234

  tls {
    dns cloudflare <API-token>
  }
}

8. Start Caddy

sudo mkdir /etc/caddy/
sudo nano /etc/caddy/Caddyfile

sudo systemctl daemon-reload
sudo systemctl enable caddy
sudo systemctl start caddy

And that’s it!