从 nginx 迁移到 caddy

2021-12-11

想尝试一下 HTTP3/QUIC 协议,但是 nginx 没有原生支持 QUIC,我把小站的代理从 nginx 更换成了 caddy,这里记录一下 caddy 的配置过程。

最终效果

chrome 已经支持了 QUIC 协议,我们可以从响应头上看出:

alt-svc 字段表示 alternative service 之意。表示在常规服务之外的替代品。

有这个字段就说明服务端已经开启了 QUIC 协议。

caddy 配置文件路径

caddy 配置文件默认文件名是 Caddyfile, 放置于 /etc/caddy/ 目录下:

/etc/caddy/Caddyfile

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

rewriteredir 的区别是:rewrite 仅仅是服务器内部的处理,直接修改返回响应的内容,用户看不到 URL 上的变换,也不知道网络背后发生的事情。而 redir 则提示用户的浏览器重新请求到另一个 URL

实现 redir

我的网站 希望将下面两种情况的请求都 301 重定向到 上述配置的站点 中去,这时候就需要 redir 指令:

在 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 的语法格式。

捐助本站

为了保证阅读体验,本站不安放广告。但是,租用服务器和编写文章需要个人资金和时间的投入。

如果您觉得文章对您有用,请考虑捐助小站(金额不限),以期待更多原创文章。捐助记录

本站是个人网站,若无特别说明,文章均为原创,并采用 署名协议 CC-BY-NC 授权。
欢迎转载,惟请保留原文链接,且不得用于商业用途。