想尝试一下 HTTP3/QUIC 协议,但是 nginx 没有原生支持 QUIC,我把小站的代理从 nginx 更换成了 caddy,这里记录一下 caddy 的配置过程。 最终效果 chrome 已经支持了 QUIC 协议,我们可以从响应头上看出: alt-svc 字段表示 alternative service 之意。表示在常规服务之外的替代品。 有这个字段就说明服务端已经开启了 QUIC 协议。 caddy 配置文件路径 caddy 配置文件默认文件名是 Caddyfile, 放置于 /etc/caddy/ 目录下: caddy 配置文件结构 按照 caddy 官方文档 的介绍,Caddyfile 的基本结构有三部分: 一个原则 配置文件有一个原则: 当参数只有一个时,大括号 { } 可以省略 当参数有多个时,参数可以扩展为大括号 { } 全局配置(可选) global options block, 全局开关。 代码片段(可选) 类似函数的作用,是可以复用的逻辑。 站点配置(必选) 每个站点的具体配置,以站点地址开始。 下面介绍一些基本的写法: 启用 QUIC 协议 caddy 对 QUIC 协议的支持不是默认打开的,需要在配置文件 /etc/caddy/Caddyfile 的最开头加上: // /etc/caddy/Caddyfile { servers { protocol { experimental_http3 } } } 作为 global 全局配置 站点配置 单个站点的配置,需要写在以站点地址为开头的 { } 中: 比如我的站点的配置,基本框架就是 www.lfhacks.com { directive 1... directive 2... directive 3... } directive 是针对站点的配置指令,可以去的值 参考这里 下面介绍各个 directive 文档根路径 root 表示服务器本地目录, root * /var/www/html 表示将 URL 的根目录映射到 /var/www/html 目录。 但是仅仅设置 root 目录并不能让 caddy 开启静态文件下载服务。还需要另一个指令配合。 静态文件支持 file_server file_server 这个指令提供静态文件下载服务,把 URI 请求里的相对路径转化为请求服务器相对 root 目录 的请求。 比如:当请求采取如下形式:caddy.com/aaa,会寻找 /var/www/html/aaa 目录 打开 gzip 使用 encode 指令: encode gzip 支持 php 使用 php_fastcgi 指令,和 nginx 配置类似。 假如 nginx 的站点配置为: fastcgi_pass unix:/run/php/php7.2-fpm.sock; 那么 caddy 设置应为: php_fastcgi unix//run/php/php7.2-fpm.sock https 证书 caddy 自带 https, 你什么都不做,就自动支持 https。但是如果你已经有了证书,也是可以配置的。使用 tls 指令。 tls your.crt your.key 错误处理 异常处理,类似 nginx 的: error_page 404 /404.html; 如果出现 404 错误,将直接返回 404.html 的内容 caddy 使用 handle_errors 指令: handle_errors { rewrite * /{http.error.status_code}.html file_server } 日志配置 log 使用 log 指令配置日志,caddy 默认的日志格式是结构化的 json 格式,有一下几个方面的配置: 输出形式 使用 log 下一级指令 output 如下: output file /var/log/caddy/access.log { roll_size 100MiB roll_keep 30 roll_keep_for 24h } output 规定了日志输出的方向,file 表示输出到文件, 后面跟上文件的路径。 roll_size 表示日志文件的最大体积,到达这一体积后,即重新创建日志文件,原来的文件改名。 roll_keep 表示转储文件的最多保持数量,超过这一数量的旧日志文件将被删除。 roll_keep_for 表示转储文件的最大保存时间,超过这一时间的旧日志文件将被删除。 输出格式 使用 format 指令规定输出日志的格式。默认的日志时间格式是时间戳格式,不方便阅读和解析。用下面的指令可以输出为 iso 格式 format json { time_format "iso8601" } 输入的时间格式类似如 2021-11-15T17:39:14.604+0800 的格式: 日志级别 可以规定输入日志的级别,因为本文件是 access.log,所以只需要 INFO 级别。用下面的子指令实现: level INFO 实现 rewrite 使用 rewrite 指令实现 rewrite,比如: rewrite /rss/ /index.xml rewrite 和 redir 的区别是:rewrite 仅仅是服务器内部的处理,直接修改返回响应的内容,用户看不到 URL 上的变换,也不知道网络背后发生的事情。而 redir 则提示用户的浏览器重新请求到另一个 URL 实现 redir 我的网站 希望将下面两种情况的请求都 301 重定向到 上述配置的站点 中去,这时候就需要 redir 指令: http://lfhacks.com http://www.lfhacks.com https://lfhacks.com 在 caddy 中的配置是,新建立站点,然后 redir 到你想要的域名,比如: http://lfhacks.com, https://lfhacks.com, http://www.lfhacks.com { redir https://www.lfhacks.com{uri} permanent } 结论 caddy 的配置相比 nginx 短小很多,同样一件事情, nginx 需要多级别的嵌套才能说明,而 caddy 则放置在同一个文件里。 缺点就是学习成本较高,对于已经十分熟悉 nginx 的人,并没有太多的动力去学习 caddyfile 的语法格式。