升级指南
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,请执行步骤 1。说真的——我们无法强调至少了解如何使用 Caddy 2 的重要性。(它更有趣!)
- 使用以下指南来转换您的
caddy
命令。 - 使用以下指南来转换您的 Caddyfile。
- 在本地或暂存环境中测试您的新配置。
- 测试、测试、再测试
- 部署并享受乐趣!
HTTPS 和端口
Caddy 的默认端口不再是 :2015
。Caddy 2 的默认端口是 :443
,或者如果不知道主机名/IP,则为端口 :80
。您始终可以在配置中自定义端口。
Caddy 2 的默认协议是 始终 HTTPS(如果知道主机名或 IP)。这与 Caddy 1 不同,在 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 中,请求匹配 功能更强大。任何将中间件添加到 HTTP 处理程序链或以任何方式操作 HTTP 请求/响应的 v2 指令都利用了这种新的匹配功能。详细了解 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 基本身份验证仍然使用 basicauth
指令配置。但是,Caddy 2 配置不接受纯文本密码。您必须对其进行哈希处理,caddy hash-password
可以帮助您完成此操作。
- v1
basicauth /secret/ Bob hiccup
- v2
basicauth /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 格式。如果您出于遗留原因仍然需要以通用日志格式 (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
添加路径前缀,然后使用 without
使用 proxy
删除相同前缀的 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、进行内部子请求、解析前置 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 地址的开发主机名提供本地可信证书。
大多数站点根本不需要此指令。
服务文件
我们建议使用 我们官方的 systemd 服务文件之一 来部署 Caddy。
如果您需要自定义服务文件,请以我们的服务文件为基础。它们经过精心调整,以达到最佳效果!如果需要,请务必自定义您的服务文件。
插件
为 v1 编写的插件不会自动与 v2 兼容。许多 v1 插件在 v2 中甚至不需要。另一方面,v2 比 v1 更易于扩展和灵活!
如果您想为 Caddy 2 编写插件,请 学习如何编写 Caddy 模块。
使用插件构建 Caddy 2
可以在 交互式下载页面 上下载包含插件的 Caddy 2。或者,您可以使用 xcaddy
自己构建 Caddy 并选择要包含的插件。xcaddy
自动执行 Caddy 的 main.go 文件中的说明。
获取帮助
如果您在使用 Caddy 时遇到问题,请先查看我们的网站以获取文档。花时间尝试新事物并了解正在发生的事情 - v2 在很多方面与 v1 非常不同(但它也很熟悉)!
如果您仍然需要帮助,请加入 我们的社区!您可能会发现帮助他人是帮助自己的最佳方式。