Prepare LXC
- Unprivileged container
- Ubuntu 24.04
Create a user with name caddy
, we will run caddy with this user.
- For Ubuntu LXC templates, by default, there won’t be a 1000:1000 user:group pair be created.
- Ubuntu LXC template by default will throw you in a shell with ‘root’ user.
groupadd -g 1000 caddy
useradd -u 1000 -g 1000 -m -s /bin/bash caddy
There is no need to set password for this user.
Download Caddy
I’m using cloudflare as my domain provider, so this note will focus on CloudFlare.
- Donwload the
caddy
binary with CloudFlare module baked in- https://caddyserver.com/download
- Change the ‘platform’ to match your hardware and OS.
- Make sure you’ve selected ‘dns-provider/cloudflare’ module
- Download with
curl -o caddy "<download_url>"
.
- https://caddyserver.com/download
Then, we just move caddy binary to correct location:
mv caddy /usr/local/bin/
chmod a+x /usr/local/bin/caddy
Verify ‘cloudflare’ module is there:
caddy list-modules
# my output:
# dns.providers.cloudflare
# Non-standard modules: 1
Config Caddyfile
Usually we put it in /etc/caddy/Caddyfile
awesome.dev, *.awesome.dev {
# Configure Automatic HTTPS with a wildcard certificate
# using the DNS-01 challenge.
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
# This is where you define how to handle the traffic.
# Caddy can route requests based on the subdomain used.
@blog host blog.awesome.dev
handle @blog {
reverse_proxy 192.168.217.12:3456
}
# Fallback for any other subdomain or the main domain
handle {
reverse_proxy localhost:80
}
}
WARNING
The blank space between
@blog
and{
must be there. I.e.handle @blog{
is invalid, it must behandle @blog {
.
The env.CLOUDFLARE_API_TOKEN
will be obtained from cloudflare and passed in via systemd config.
CloudFlare API Token
- Log in to your Cloudflare dashboard.
- Go to My Profile > API Tokens.
- Click Create Token.
- Find the “Edit zone DNS” template and click Use template.
- Configure the token:
- Token name: Give it a descriptive name, like “Caddy DNS-01 Token”.
- Permissions: The “Zone: DNS: Edit” permission should already be selected. This is what Caddy needs.
- Zone Resources: Select “Specific zone” and choose awesome.dev from the dropdown list. This is crucial for security, as it limits the token’s power to only that specific domain.
- Click Continue to summary, then click Create Token.
- Copy the generated token immediately! Cloudflare will only show it to you once. Store it securely.
Systemd
Config Location: /etc/systemd/system/caddy.service
:
[Unit]
Description=Caddy Web Server
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/local/bin/caddy run --config /etc/caddy/Caddyfile
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
Environment="CLOUDFLARE_API_TOKEN=<your_token>"
[Install]
WantedBy=multi-user.target
For debugging you can use to print all env variables (--environ
):
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile
Then, to load it:
systemctl daemon-reload # <- this will refresh the actual configs in-use by systemd
systemctl enable caddy.service
systemctl start caddy.service