文档
一个 项目

升级指南

Caddy 2 是一个全新的代码库,从头重写,以改进 Caddy 1。Caddy 2 与 Caddy 1 不向后兼容。但别担心,对于大多数基础设置,变化并不大。本指南将帮助你尽可能轻松地完成迁移。

本指南不会深入介绍可用的新功能——顺带一提,它们确实很酷,你应该学习它们——这里的目标只是让你快速在 Caddy 2 上启动并运行。

高阶要点

  • “Caddy 2” 仍然只叫作 caddy。我们有时会使用 “Caddy 2” 来澄清版本以减少迁移时的混淆。
  • 大多数用户只需要替换他们的 caddy 可执行文件和更新后的 Caddyfile 配置(在测试其可用性后)。
  • 最好以不带有 Caddy 1 预设假设的心态来使用 Caddy 2。
  • 你可能无法在 v2 中完美复刻某些非常小众的 v1 配置。通常这是有原因的。
  • 命令行不再用于服务器配置。
  • 环境变量不再用于配置。
  • 给 Caddy 2 提供配置的主要方式是通过其API,但也可以使用caddy 命令
  • 你应该知道 Caddy 2 的原生配置语言是 JSON,Caddyfile 只是将配置转换为 JSON 的另一种配置适配器。极其定制/高级的用例可能需要直接使用 JSON,因为并非所有可能的配置都能用 Caddyfile 表达。
  • Caddyfile 大体相同,但更强大;指令发生了变化。

步骤

  1. 通过我们的入门指南熟悉 Caddy 2。
  2. 如果你还没做第 1 步,请先做。认真的 —— 我们无法强调至少了解如何使用 Caddy 2 是多么重要。(而且这更有趣!)
  3. 使用下面的指南迁移你的 caddy 命令。
  4. 使用下面的指南迁移你的 Caddyfile。
  5. 在本地或预发环境测试你的新配置。
  6. 测试,再测试,继续测试
  7. 部署并享受吧!

HTTPS 和端口

Caddy 的默认端口不再是 :2015。Caddy 2 的默认端口是 :443,如果未知主机名/IP,则为 :80。你始终可以在配置中自定义端口。

Caddy 2 的默认协议是在已知主机名或 IP 时始终使用 HTTPS。这与 Caddy 1 不同,Caddy 1 默认仅对公开可见的域名使用 HTTPS。现在,每个 站点都会使用 HTTPS(除非你通过显式指定端口 :80 或使用 http:// 来禁用它)。

IP 地址和 localhost 域名将由一个本地信任的内嵌 CA签发证书。所有其他域名将使用 ZeroSSL 或 Let's Encrypt。(这些都是可配置的。)

证书和 ACME 资源的存储结构已更改。Caddy 2 可能会为你的网站获取新证书;但如果你有大量证书,也可以手动迁移它们(如果程序没有为你迁移的话)。详情见 issue #2955#3124

命令行

caddy 命令现在是 caddy run

所有命令行标志都不同了。把它们移除;所有服务器配置现在都存在于实际的配置文档中(通常是 Caddyfile 或 JSON)。你很可能能在 JSON 结构Caddyfile 全局选项 中找到替代大多数 v1 命令行标志的配置方法。

caddy -conf ../Caddyfile 这样的命令将变为 caddy run --config ../Caddyfile

和以前一样,如果你的 Caddyfile 在当前文件夹,Caddy 会自动查找并使用它;在这种情况下你无需使用 --config 标志。

信号大致相同,但不再支持 USR1 和 USR2。请使用 caddy reload 命令或API来加载新配置。

以前运行 caddy 而不带任何配置会启动一个简单的文件服务器。Caddy 2 的等价命令是 caddy file-server

环境变量不再相关,除了 HOME(以及可选的任何你设置的 XDG_* 变量)。CADDYPATH 已被操作系统约定替代

Caddyfile

V2 的 Caddyfile 与你已熟悉的非常相似。你需要做的主要事情是更改指令。

⚠️ 务必深入阅读新的指令! 尤其是如果你的配置比较复杂,有很多细微差别需要考虑。这些提示会让你大部分配置快速切换过来,但请务必阅读每个指令的完整文档,以便理解升级的影响。当然,在将配置投入生产之前,总是要彻底测试。

主要变化

  • 如果你提供静态文件服务,你需要添加一个 file_server 指令,因为 Caddy 2 默认不会启用静态文件服务。出于安全原因,Caddy 2 默认也不会嗅探 MIME;如果缺少 Content-Type,你可能需要使用 header 指令自行设置该头。

  • 在 v1 中,你只能按请求路径来过滤(或“匹配”)指令。在 v2 中,请求匹配 更加强大。任何在 v2 中将中间件添加到 HTTP 处理链或以任何方式操纵 HTTP 请求/响应的指令,都可以使用这种新的匹配功能。阅读更多关于 v2 请求匹配器的内容。你需要了解它们才能理解 v2 Caddyfile。

  • 虽然许多占位符 与以前相同,但也有许多已更改,并且现在有很多新占位符,包括Caddyfile 的简写占位符

  • Caddy 2 的日志都是结构化的,默认格式为 JSON。所有日志级别都可以简单地发送到同一个日志以便处理(但如果需要你可以自定义)。

  • 在 Caddy 1 中按路径前缀匹配请求的地方,Caddy 2 中的路径匹配现在默认是精确匹配。如果你想匹配像 /foo/ 这样的前缀,在 Caddy 2 中需要写成 /foo/*

下面我们列出了一些最常见的 v1 指令,并描述如何将它们转换以在 v2 Caddyfile 中使用。

⚠️ 仅因为此页中缺少某个 v1 指令并不意味着 v2 无法实现它! 有些 v1 指令不再需要、不能很好地转换,或在 v2 中以其他方式实现。对于某些高级定制,你可能需要降到 JSON 层面来完成。请浏览我们的文档以找到你需要的内容!

basicauth

HTTP 基本认证仍然使用 basic_auth 指令配置。然而,Caddy 2 的配置不接受明文密码。你必须对密码进行哈希,caddy hash-password 可以帮你完成这项工作。

  • v1:
basicauth /secret/ Bob hiccup
  • v2:
basic_auth /secret/* {
	Bob JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX
}

browse

文件浏览现在通过 file_server 指令启用。

  • v1:
browse /subfolder/
  • v2:
file_server /subfolder/* browse

errors

自定义错误页可以通过 handle_errors 实现。

  • v1:
errors {
	404 404.html
	500 500.html
}
  • v2:
handle_errors {
	rewrite * /{err.status_code}.html
	file_server
}

ext

隐含文件扩展名可以用 try_files 实现。

  • v1: ext .html
  • v2: try_files {path}.html {path}

fastcgi

假设你在提供 PHP 服务,v2 等价为 php_fastcgi

  • v1:
fastcgi / localhost:9005 php
  • v2:
php_fastcgi localhost:9005

注意 v1 的 fastcgi 指令在内部做了很多工作,包括在磁盘上尝试文件、重写请求,甚至重定向。v2 的 php_fastcgi 指令也为你完成了这些事情,但文档给出了可以修改的展开形式,以便在需求不同的情况下调整。

v2 中不需要 php 预设,因为 php_fastcgi 默认假定使用 PHP。像 php_fastcgi 127.0.0.1:9000 php 这样的行会导致反向代理认为存在第二个名为 php 的后端,从而引起连接错误。

子指令在 v2 中有所不同 —— 对于 PHP,大多数情况下你可能不需要任何子指令。

gzip

现在使用一个单一指令 encode 来处理所有响应编码,包括多种压缩格式。

  • v1:
gzip
  • v2:
encode gzip

有趣的是:Caddy 2 还支持 zstd(不过目前没有浏览器支持)。

大体不变,但在 v2 中更强大,因为它可以做子字符串替换。

  • v1:
header / Strict-Transport-Security max-age=31536000;
  • v2:
header Strict-Transport-Security max-age=31536000;

log

启用访问日志;log 指令在 v2 中仍可使用,但所有日志默认都是结构化的、以 JSON 编码。

推荐的启用访问日志的方式很简单:

log

该配置会向 stderr 输出结构化日志。(你也可以输出到文件或网络套接字;参见log 指令文档。)

默认情况下,日志将采用结构化 的 JSON 格式。如果你仍然因兼容原因需要使用通用日志格式(CLF),可以使用 transform-encoder 插件。

proxy

v2 的对应为 reverse_proxy

值得注意的子指令变化是 header_upstreamheader_downstream 已分别变为 header_upheader_down;与负载均衡相关的子指令以 lb_ 前缀命名。

另一个重要差异是 v2 代理默认会透传所有传入头(包括 Host 头)并设置 X-Forwarded-For 头。换言之,v1 的 “transparent” 模式在 v2 中基本就是默认行为(但如果你需要其他头例如 X-Real-IP,你必须自己设置)。你仍然可以使用 header_up 子指令覆盖/自定义 Host 头。

WebSocket 代理在 v2 中“开箱即用”;不需要像 v1 那样“启用” websockets。

without 子指令已被移除,因为得益于更强的匹配器支持,v2 中不再需要rewrite 改造技巧

  • v1:
proxy / localhost:9005
  • v2:
reverse_proxy localhost:9005

redir

未改变,除了一些关于可选状态码参数的细节。大多数配置无需做任何修改。

  • v1: redir https://example.com{uri}
  • v2: redir https://example.com{uri}

rewrite

请求重写(“内部重定向”)的语义略有变化。如果你在 v1 中使用所谓的 “rewrite 改造技巧” 来作为按非简单路径前缀匹配请求的办法,在 v2 中这完全不必要。

新的 rewrite 指令 非常简单但很强大,因为大部分复杂性由 v2 中的匹配器 处理:

  • v1:
rewrite {
	if {>User-Agent} has mobile
	to /mobile{uri}
}
  • v2:
@mobile {
	header User-Agent *mobile*
}
rewrite @mobile /mobile{uri}

注意我们只是使用 Caddy 2 常用的匹配器标记;对于该指令不再是特殊情况。

首先移除所有 rewrite 改造技巧;将它们改为命名匹配器。评估每个 v1 的 rewrite 看看在 v2 中是否真的需要。提示:如果 v1 的 Caddyfile 使用 rewrite 来添加路径前缀,然后用 proxywithout 来移除同一前缀,那就是一个 rewrite 改造技巧,可以被消除。

你可能会发现新的 routehandle 指令在对高级路由逻辑进行更精细控制时非常有用。

root

未改变,但如果你的 root 路径以 / 开头,你需要添加一个 * 匹配器标记以将其与路径匹配器 区分开来。

  • v1: root /var/www
  • v2: root * /var/www

因为在 v2 中它接受一个匹配器,这意味着你也可以根据请求改变站点根目录。

如果提供静态文件服务,记得添加file_server 指令,因为 Caddy 2 不再默认启用静态文件服务,而 v1 则默认启用。

status

v2 的对应为 respond,它也能写回响应体。

  • v1:
status 404 /secrets/
  • v2:
respond /secrets/* 404

templates

templates 指令的总体语法保持不变,但实际的模板动作/函数已不同并大幅改进。例如,模板现在能够包含文件、渲染 Markdown、发起内部子请求、解析 front matter 等等!

查看文档 了解新函数的细节。

  • v1: templates
  • v2: templates

tls

tls 指令的基本原理未改变,例如指定你自己的证书和私钥:

  • v1: tls cert.pem key.pem
  • v2: tls cert.pem key.pem

但 Caddy 的自动 HTTPS 逻辑确实发生了变化,请注意!

密码套件名称也已更改。

在 Caddy 2 中,一个常见配置是使用 tls internal,让其为非 localhost 且不是 IP 地址的开发主机名提供本地信任的证书。

大多数站点根本不需要使用该指令。

服务文件

我们建议在 Caddy 部署中使用我们官方的 systemd 服务文件之一

如果你需要自定义服务文件,请以我们的为基础。它们经过了精心调优,背后有充分的理由!如有需要,务必对你的文件进行定制。

插件

为 v1 编写的插件不会自动兼容 v2。许多 v1 插件在 v2 中甚至不再需要。另一方面,v2 比 v1 更容易扩展且更灵活!

如果你想为 Caddy 2 编写插件,学习如何编写 Caddy 模块

使用插件构建 Caddy 2

可以在交互式下载页面下载带插件的 Caddy 2。或者,你也可以使用 xcaddy 自行构建 Caddy,并选择包含哪些插件。xcaddy 会自动化 Caddy 的 main.go 文件中的指令。

获取帮助

如果你在让 Caddy 工作时遇到困难,请先查看我们网站上的文档。花时间尝试新事物并理解发生了什么——v2 在很多方面与 v1 很不同(但也非常熟悉)!

如果你仍然需要帮助,请加入我们的社区!你可能会发现帮助别人也是帮助自己的最好方式。