https://caddyserver.com/docs/


安装

debian系

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 

chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg 
chmod o+r /etc/apt/sources.list.d/caddy-stable.list 
sudo apt update 
sudo apt install caddy

安装好之后caddy查看帮助,caddy run在当前终端运行。

下下来版本会有点老。

解决方法:添加 Caddy 官方仓库

# 安装必要工具
sudo apt update
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

# 导入 GPG key
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
  sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

# 添加 APT 源
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
  sudo tee /etc/apt/sources.list.d/caddy-stable.list

# 更新并安装 Caddy
sudo apt update
sudo apt install caddy

源码编译

  1. 安装Git
  2. 安装go>=1.20
  3. 拉取caddy代码
  4. 进入./caddy/cmd/caddy,运行go build
  5. 编译产物会在~/go/bin

带插件版本

caddy解压后为一个单个文件,只需要和caddyfile搭配使用即可,因此如果想要安装一些额外插件就得下载带插件编译的版本。有两种方式:直接去官网勾选插件然后下载,或者使用xcaddy

简单使用

# 阻塞使用
caddy run
# 检查输出配置&带配置运行,如果在当前路径则可不带配置
caddy adapt --config /path/to/Caddyfile
caddy run --config /path/to/Caddyfile
# 返回当前配置
curl localhost:2019/config/
# 格式化caddyfile
caddy fmt --overwrite
# 后台运行
caddy start
caddy stop
# 热更新配置
caddy reload
# 恢复上一次成功的配置
caddy run --resume

配置Caddyfile

几种示例

# 全局配置:ACME 邮箱 + DNS 提供商
{
    email [email protected]          # Let’s Encrypt 账户邮箱
    acme_dns alidns {
        access_key_id     YOUR_ACCESS_KEY_ID
        access_key_secret YOUR_ACCESS_KEY_SECRET
    }
}

# 泛域名站点:*.example.com(含根域)
*.example.com {
    # 申请并维护通配符证书
    tls {
        dns alidns {
            access_key_id     YOUR_ACCESS_KEY_ID
            access_key_secret YOUR_ACCESS_KEY_SECRET
        }
    }

    # 反向代理到本机 9000
    reverse_proxy 127.0.0.1:9000
}

# 根域单独写一行(部分 DNS 面板把根域和 * 分开)
example.com {
    # 复用上面同一套证书
    tls {
        dns alidns {
            access_key_id     YOUR_ACCESS_KEY_ID
            access_key_secret YOUR_ACCESS_KEY_SECRET
        }
    }

    reverse_proxy 127.0.0.1:9000
}

# 80 端口强制跳转 HTTPS
http://example.com, http://*.example.com {
    redir https://{host}{uri} permanent
}

简化版:

{
    email [email protected]
    acme_dns alidns {
        access_key_id     {$ALIDNS_ACCESS_KEY_ID}
        access_key_secret {$ALIDNS_ACCESS_KEY_SECRET}
    }
}

example.com, *.example.com {
	reverse_proxy 127.0.0.1:9000
	log {
		output file /opt/caddy/logs/access.log {
			roll_size 100mb
			roll_keep 5
			roll_keep_for 720h
		}
		format json
	}
}

最终版:

# 全局配置:ACME 邮箱 + DNS 提供商
{
	email [email protected] # Let’s Encrypt 账户邮箱
	acme_dns alidns {
		access_key_id     {$ALIDNS_ACCESS_KEY_ID}
        access_key_secret {$ALIDNS_ACCESS_KEY_SECRET}
	}
}

*.example.com {
	log {
		output file /var/log/caddy/access.log {
			roll_size 20mb
			roll_keep 5
			roll_keep_for 720h
		}
		format json
	}

	@a host a.example.com
	reverse_proxy @a 192.168.1.123:8088

	@b host b.example.com
	reverse_proxy @b 127.0.0.1:8080
}

检验正确性

# --validate 只做语法检查,不会真正启动服务
caddy validate

# 如果想指定配置文件名:
caddy validate --config ./Caddyfile.prod

# 格式化
caddy fmt --overwrite

守护进程启动

虽然Caddy可以通过直接使用它的命令行界面成功运行,但使用服务管理器来保持它的运行有很多好处,例如确保它在系统启动时重新启动,并捕捉stdout/stderr日志。

官方的caddy.service文件:(注意具体文件路径是否匹配)

# 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]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

将其放到/etc/systemd/system/下。

# 0. 把二进制放到 /usr/local/bin/caddy(或你喜欢的路径)
sudo cp ./caddy /usr/local/bin/caddy
sudo chmod +x /usr/local/bin/caddy

# 1. 创建专用用户 & 目录
sudo groupadd --system caddy
sudo useradd --system --gid caddy --create-home --home-dir /var/lib/caddy --shell /usr/sbin/nologin caddy
sudo mkdir -p /etc/caddy
sudo chown -R caddy:caddy /etc/caddy /var/lib/caddy
sudo chown caddy:caddy /var/log/caddy/

# 2. 放入 Caddyfile
sudo cp ./Caddyfile /etc/caddy/Caddyfile
sudo chown caddy:caddy /etc/caddy/Caddyfile

# 3. 启用并启动
sudo systemctl daemon-reload
sudo systemctl enable --now caddy

如果启动报错了可以用sudo journalctl -u caddy -f检查。一般如果手动执行ExecStart命令是正常而通过systemd执行出错就是权限问题。

# 实时跟踪
sudo journalctl -u caddy -f

# 只看最近 100 行
sudo journalctl -u caddy -n 100

# 带时间戳、分页浏览
sudo journalctl -u caddy --no-pager -o short-iso

# 指定时间段
sudo journalctl -u caddy --since "2025-08-08 10:00" --until "2025-08-08 11:00"

PS.感觉systemd还是有点奇奇怪怪的问题,每次要重启才能成功注册一个证书,由于reload时会注册好所有证书才会返回成功,因此systemctl reload caddy会反复触发timeout无法成功。不知道续签会不会有问题。

只要配置没有错误,Caddy就会全自动申请对应的泛域名证书。当通过该域名访问caddy的443端口时,就会建立https连接了。