文档
一个 项目

使 Caddy 持续运行

虽然可以直接使用 Caddy 的命令行界面运行 Caddy,但使用服务管理器来保持其运行有诸多优点,例如确保系统重启时自动启动并捕获 stdout/stderr 日志。

Linux 服务

在使用 systemd 的 Linux 发行版上,推荐使用我们官方的 systemd 单元文件来运行 Caddy。

Unit 文件

我们提供了两种不同的 systemd 单元文件,你可以根据使用场景选择:

  • caddy.service —— 如果你使用 Caddyfile 来配置 Caddy。若你更喜欢使用其他配置适配器或 JSON 配置文件,可以覆盖 ExecStartExecReload 命令。

  • caddy-api.service —— 如果你仅通过其 API 配置 Caddy。该服务使用 --resume 选项,这将使用默认持久化autosave.json 启动 Caddy。

它们非常相似,但在 ExecStartExecReload 命令上有所不同,以适应不同的工作流程。

如果需要在这两种服务之间切换,应在启用并启动另一个服务之前先禁用并停止之前的服务。例如,要从 caddy 服务切换到 caddy-api 服务:

sudo systemctl disable --now caddy
sudo systemctl enable --now caddy-api

手动安装

一些安装方法会自动将 Caddy 设置为以服务运行。如果你选择的方法没有这样做,可以按照以下说明操作:

需求:

  • 你已下载从源码构建caddy 二进制文件
  • systemctl --version 需为 232 或更新版本
  • sudo 权限

将 caddy 二进制文件移入你的 $PATH,例如:

sudo mv caddy /usr/bin/

测试是否生效:

caddy version

创建名为 caddy 的用户组:

sudo groupadd --system caddy

创建一个名为 caddy 的用户,并带有可写的主目录:

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

如果使用配置文件,请确保该配置文件对你刚创建的 caddy 用户可读。

接下来,根据你的使用场景选择一个 systemd 单元文件

再次确认 ExecStartExecReload 指令。 确保二进制位置和命令行参数与您的安装相符!例如:如果使用配置文件,请根据实际情况修改 --config 路径(若与默认不同)。

通常将服务文件保存到:/etc/systemd/system/caddy.service

保存服务文件后,可以通过常用的 systemctl 操作首次启动服务:

sudo systemctl daemon-reload
sudo systemctl enable --now caddy

验证其是否正在运行:

systemctl status caddy

现在你就可以使用该服务了!

使用服务

如果使用 Caddyfile,可以使用 nanovi 或你喜欢的编辑器编辑配置:

sudo nano /etc/caddy/Caddyfile

你可以将静态站点文件放在 /var/www/html/srv 中。确保 caddy 用户有权限读取这些文件。

要验证服务是否正在运行:

systemctl status caddy

status 命令还会显示当前正在运行的服务文件的位置。

当使用我们的官方服务文件运行时,Caddy 的输出将被重定向到 journalctl。要读取完整日志并避免行被截断:

journalctl -u caddy --no-pager | less +G

如果使用配置文件,在进行更改后可以优雅地重新加载 Caddy:

sudo systemctl reload caddy

你可以使用以下命令停止服务:

sudo systemctl stop caddy

Caddy 进程将以 caddy 用户身份运行,其 $HOME 被设置为 /var/lib/caddy。这意味着:

  • 默认的数据存储位置(用于证书及其他状态信息)将是 /var/lib/caddy/.local/share/caddy
  • 默认的配置存储位置(用于自动保存的 JSON 配置,主要对 caddy-api 服务有用)将是 /var/lib/caddy/.config/caddy

使用 systemd 的本地 HTTPS

在本地开发使用 HTTPS 时,你可能会使用像 localhostapp.localhost 这样的主机名。这将启用使用 Caddy 本地 CA 签发证书的本地 HTTPS

由于以服务方式运行时 Caddy 会以 caddy 用户运行,因此它没有权限将其根 CA 证书安装到系统信任存储。为此,请运行 sudo caddy trust 来执行安装。

如果你希望在使用 internal issuer 时其他设备也能连接到你的服务器,则需要在那些设备上也安装根 CA 证书。你可以在 /var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt 找到根 CA 证书。许多 Web 浏览器现在使用自己的信任存储(忽略系统的信任存储),因此你可能还需要在浏览器中手动安装该证书。

覆盖配置

覆盖服务文件某些配置的最佳方式是使用以下命令:

sudo systemctl edit caddy

这会在你的默认终端文本编辑器中打开一个空文件,你可以在其中覆盖或添加单元定义指令。这称为“drop-in” 文件。

环境变量

如果你需要为配置定义环境变量,可以像下面这样做:

[Service]
Environment="CF_API_TOKEN=super-secret-cloudflare-tokenvalue"

类似地,如果你更愿意将环境变量保存在单独文件(envfile)中,可以使用 EnvironmentFile 指令,如下:

[Service]
EnvironmentFile=/etc/caddy/.env

那么你的 /etc/caddy/.env 文件可以如下(不要在值周围使用 " 引号):

CF_API_TOKEN=super-secret-cloudflare-tokenvalue

runreload 覆盖

如果需要将配置文件从默认的 Caddyfile 更改为使用 JSON 文件(注意 Exec* 指令在设置新值之前必须先用空字符串重置):

[Service]
ExecStart=
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/caddy.json
ExecReload=
ExecReload=/usr/bin/caddy reload --config /etc/caddy/caddy.json

崩溃时重启

如果你希望在 Caddy 意外崩溃后 5 秒内自动重启:

[Service]
# 如果退出代码不是 1,则自动重启 caddy
RestartPreventExitStatus=1
Restart=on-failure
RestartSec=5s

然后,保存文件并退出文本编辑器,重启服务以使其生效:

sudo systemctl restart caddy

SELinux 注意事项

在启用 SELinux 的系统上,你有两个选择:

  1. 使用 COPR 仓库 安装 Caddy。你的 systemd 文件和 caddy 二进制文件将已被正确创建并标记(因此你可以忽略本节)。如果你希望使用自定义构建的 Caddy,则需要按下文所述标记可执行文件。

  2. 从本站下载 Caddy或使用 xcaddy 编译。在任一情况下,你都需要自己标记文件。

Systemd 单元文件及其可执行文件在未被标记为 systemd_unit_file_tbin_t 时不会被运行。

systemd_unit_file_t 标签会自动应用于创建在 /etc/systemd/... 下的文件,所以请确保按手动安装 的说明将 caddy.service 文件创建在那里。

要标记 caddy 二进制文件,你可以使用以下命令:

semanage fcontext -a -t bin_t /usr/bin/caddy && restorecon -Rv /usr/bin/caddy

Windows 服务

在 Windows 上以服务方式运行 Caddy 有两种方法:sc.exeWinSW

sc.exe

创建服务,请运行:

sc.exe create caddy start= auto binPath= "YOURPATH\caddy.exe run"

(将 YOURPATH 替换为实际的 caddy.exe 路径)

启动:

sc.exe start caddy

停止:

sc.exe stop caddy

WinSW

按下述说明在 Windows 上将 Caddy 安装为服务。

需求:

  • 你已下载从源码构建caddy.exe 二进制文件
  • 来自最新发布版本的任意 .exe,来自 WinSW 服务包装器(下面的服务配置为 v2.x 发行版 编写)

将所有文件放入一个服务目录。以下示例中我们使用 C:\caddy

WinSW-x64.exe 文件重命名为 caddy-service.exe

在相同目录下添加 caddy-service.xml

<service>
  <id>caddy</id>
  <!-- Display name of the service -->
  <name>Caddy Web Server (powered by WinSW)</name>
  <!-- Service description -->
  <description>Caddy Web Server (https://caddyserver.com/)</description>
  <executable>%BASE%\caddy.exe</executable>
  <arguments>run</arguments>
  <log mode="roll-by-time">
    <pattern>yyyy-MM-dd</pattern>
  </log>
</service>

现在你可以使用以下命令安装服务:

caddy-service install

你可能想打开 Windows 服务控制台查看服务是否运行正确:

services.msc

请注意,Windows 服务不能被 reload,因此你必须直接告诉 caddy 重新加载:

caddy reload

可以通过常规的 Windows 服务命令重启服务,例如通过任务管理器的 “服务” 选项卡。

如需自定义服务包装器,请参阅 WinSW 文档

Docker Compose

使用 Docker 最简单的方式是使用 Docker Compose。有关官方 Caddy Docker 镜像的更多详细信息,请参阅 Docker Hub 上的文档。

设置

首先,创建一个文件 compose.yml(或将此服务添加到你现有的文件中):

services:
  caddy:
    image: caddy:<version>
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./conf:/etc/caddy
      - ./site:/srv
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

确保将镜像的 <version> 填写为最新版本号,你可以在 Docker Hub 的 “Tags” 部分找到。

此配置的作用:

  • 使用 unless-stopped 重启策略,确保在机器重启时 Caddy 容器会自动重启。
  • 绑定端口 80443 分别用于 HTTP 和 HTTPS,同时绑定 443/udp 以支持 HTTP/3。
  • 将包含 Caddyfile 配置的 conf 目录绑定挂载到容器中。
  • site 目录绑定挂载到 /srv,用于提供站点静态文件。
  • /data/config 使用命名卷,以持久化重要信息

然后,在 conf 目录中创建一个名为 Caddyfile 的文件,并写入你的 Caddyfile 配置。

如果你有静态文件要提供,可以在与配置文件并列的目录中放一个 site/,然后使用 root * /srv 设置 root。如果没有静态文件,可以移除 /srv 的卷挂载。

如果你需要带有插件的自定义 Caddy 构建,请按照 Docker 构建说明 创建自定义 Docker 镜像。将 Dockerfilecompose.yml 放在一起,然后在 compose.yml 中将 image: 行替换为 build: .

使用

然后,你可以启动容器:

docker compose up -d

在对 Caddyfile 做出更改后重新加载 Caddy:

docker compose exec -w /etc/caddy caddy caddy reload

查看 Caddy 最近的 1000 条日志,并使用 f 跟随以查看新日志流入:

docker compose logs caddy -n=1000 -f

使用 Docker 的本地 HTTPS

在使用 Docker 本地开发并启用 HTTPS 时,你可能会使用像 localhostapp.localhost 这样的主机名。这将启用使用 Caddy 本地 CA 签发证书的本地 HTTPS。这意味着容器外的 HTTP 客户端不会信任 Caddy 提供的 TLS 证书。为了解决此问题,你可以在宿主机的信任存储中安装 Caddy 的根 CA 证书:

docker compose cp \
    caddy:/data/caddy/pki/authorities/local/root.crt \
    /usr/local/share/ca-certificates/root.crt \
  && sudo update-ca-certificates
docker compose cp \
    caddy:/data/caddy/pki/authorities/local/root.crt \
    /tmp/root.crt \
  && sudo security add-trusted-cert -d -r trustRoot \
    -k /Library/Keychains/System.keychain /tmp/root.crt
docker compose cp \
    caddy:/data/caddy/pki/authorities/local/root.crt \
    %TEMP%/root.crt \
  && certutil -addstore -f "ROOT" %TEMP%/root.crt

许多 Web 浏览器现在使用它们自己的信任存储(忽略系统的信任存储),因此你可能还需要在浏览器中手动安装该证书,使用上面从容器中复制出来的 root.crt 文件。

  • 对于 Firefox,进入 偏好设置 > 隐私与安全 > 证书 > 查看证书 > 权威机构 > 导入,然后选择 root.crt 文件。

  • 对于 Chrome,进入 设置 > 隐私与安全 > 安全性 > 管理证书 > 权威机构 > 导入,然后选择 root.crt 文件。