升级指南
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 大部分相同,但也更加强大;指令已更改。
步骤
- 通过完成我们的入门指南教程来熟悉 Caddy 2。
- 如果您还没有完成步骤 1,请执行此操作。认真地说——我们再怎么强调至少知道如何使用 Caddy 2 也是不够的。(它更有趣!)
- 使用下面的指南来转换您的
caddy
命令。 - 使用下面的指南来转换您的 Caddyfile。
- 在本地或暂存环境中测试您的新配置。
- 测试,再测试,再测试
- 部署并享受乐趣!
HTTPS 和端口
Caddy 的默认端口不再是 :2015
。Caddy 2 的默认端口是 :443
,或者,如果不知道主机名/IP,则端口为 :80
。您始终可以在配置中自定义端口。
Caddy 2 的默认协议是 始终 HTTPS,如果已知主机名或 IP。这与 Caddy 1 不同,后者仅公共外观的域名默认使用 HTTPS。现在,每个站点都使用 HTTPS(除非您通过显式指定端口 :80
或 http://
来禁用它)。
IP 地址和 localhost 域名将从 本地信任的嵌入式 CA 颁发证书。所有其他域名将使用 ZeroSSL 或 Let's Encrypt。(这一切都是可配置的。)
证书和 ACME 资源的存储结构已更改。Caddy 2 可能会为您的站点获取新证书;但是,如果您有很多证书,如果它没有为您执行此操作,您可以手动迁移它们。有关详细信息,请参见问题 #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
已被 OS 约定替换。
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
(但尚无浏览器支持)。
header
基本不变,但现在功能更强大,因为它可以在 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 格式。如果您仍然出于遗留原因需要 Common Log Format (CLF) 的日志,则可以使用 transform-encoder
插件。
proxy
v2 等效项是 reverse_proxy
。
值得注意的子指令更改是 header_upstream
和 header_downstream
已分别变为 header_up
和 header_down
;与负载均衡相关的子指令以 lb_
为前缀。
另一个显着区别是 v2 代理默认情况下传递所有传入标头(包括 Host
标头)并设置 X-Forwarded-For
标头。换句话说,v1 的“透明”模式基本上是 v2 中的默认模式(但是如果您需要其他标头(如 X-Real-IP),则必须自己设置这些标头)。您仍然可以使用 header_up
子指令覆盖/自定义 Host
标头。
Websocket 代理在 v2 中“开箱即用”;无需像 v1 中那样“启用” websocket。
without
子指令已被删除,因为由于改进的匹配器支持,重写技巧 在 v2 中不再必要。
- v1
proxy / localhost:9005
- v2
reverse_proxy localhost:9005
redir
未更改,但有关可选状态代码参数的一些细节除外。大多数配置不需要进行任何更改。
- v1:
redir https://example.com{uri}
- v2:
redir https://example.com{uri}
rewrite
请求重写(“内部重定向”)的语义略有变化。如果您在 v1 中使用所谓的“重写技巧”作为匹配除简单路径前缀之外的其他内容的请求的方式,则在 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 常用的 匹配器令牌;对于此指令,它不再是特殊情况。
首先删除所有重写技巧;将它们转换为 命名匹配器。评估每个 v1 rewrite
,看看在 v2 中是否真的需要它。提示:使用 rewrite
添加路径前缀,然后使用 proxy
和 without
删除同一前缀的 v1 Caddyfile 是重写技巧,可以消除。
您可能会发现新的 route
和 handle
指令对于更好地控制高级路由逻辑非常有用。
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、进行内部子请求、解析前端内容等等!
请参阅文档 以了解有关新功能的详细信息。
- 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 不自动兼容。v2 中甚至不需要许多 v1 插件。另一方面,v2 比 v1 更容易扩展和灵活!
如果您想为 Caddy 2 编写插件,请了解如何编写 Caddy 模块。
使用插件构建 Caddy 2
可以在交互式下载页面下载带有插件的 Caddy 2。或者,您可以使用 xcaddy
自行构建 Caddy 并选择要包含的插件。xcaddy
自动化了 Caddy 的 main.go 文件中的说明。
获取帮助
如果您正在努力使 Caddy 正常工作,请先浏览我们的网站以查找文档。花时间尝试新事物并了解正在发生的事情 - v2 在很多方面与 v1 非常不同(但它也非常熟悉)!
如果您仍然需要帮助,请加入我们的社区!您可能会发现帮助他人也是帮助自己的最佳方式。