之前听闻有个新的 Web Server,名曰 Caddy,其配置简单,还默认启用 HTTP/2,并且可以自动申请 Let’s Encrypt 的 HTTPS 证书。试用了一番,觉得不错,便把这个博客的服务程序换成了 Caddy。在这里呢,记录一下安装和配置的过程。

安装

万事第一步,先安装。

下载页面概览

打开 Caddy的下载页面,页面的内容简洁明了,左侧是 4 个要配置的项,右侧是每个配置项实际的内容。

选择运行平台

首先,选择好 Caddy 要在哪个操作系统下运行。Caddy 支持的平台还是足够多的,而且覆盖到了主流的操作系统,所以甭管您是 Windows,还是 Linux,抑或是 BSD,都可以运行 Caddy。因为我的服务器运行的是 64 位 Ubuntu,所以选择 Linux 64-bit

实话说,看到 Plan 9 的时候,心里还是被惊到了。

选择插件

接下来是选择要安装哪些插件,通常来说,根据自己的需要来选择就可以了。如果后期要安装更多的插件的话,重新来下载页面勾选需要的插件并重新安装就可以了。毕竟是用 Go 写的,最后就一个可执行文件,替换掉原来的,就算重装好了。

我的需求有这么几点:

  1. 我需要 Caddy 可以作为一个反向代理,所以选择了 http.forwardproxy 插件
  2. 我的博客的源文件放置于我的 GitHub 中,我希望 Caddy 可以直接 clone 这个仓库,并且能通过 WebHook 监听这个仓库的更新事件,所以选择了 http.git 插件
  3. 我在使用 Cloudflare 的 DNS 服务,并且 Caddy 可以通过 DNS 验证的方式申请 HTTPS 证书,所以需要 tls.dns.cloudflare 插件
  4. 我想要 Caddy 作为一个系统服务,并且可以随系统自动启动,但是我又懒得自己写配置文件,所以使用 hook.service 插件来为我提供已经写好并经过了测试的配置文件

选择是否开启遥测功能

Caddy 提供了一个叫做 “遥测” 的功能,可以监控您的 Caddy 实例的状态。具体针对该功能的描述,可以到其文档页面 Telemetry阅读。这个功能开启与否与功能无关,开不开看您心情。

选择适合您的许可证

接下来,就是选择您要使用哪一种许可证来运行 Caddy。像在下的博客是个人项目,不涉及商业应用,所以当然选择个人许可证。

下载

终于,到了下载这一步了。Caddy 提供了多种下载的方式,您可以在浏览器中将可执行文件下载到本地,或者通过命令行来下载,还可以直接使用一句话脚本来安装。

如果使用自动安装脚本的话,Caddy 会被安装到 /usr/local/bin/caddy 中。如果选择手动安装,那么需要将 Caddy 的可执行文件放到 PATH 所包含的目录中,或者将 Caddy 所在的位置加入到 PATH 中。

检查安装是否成功

完成安装后,可以直接使用 caddy 命令启动一个 Caddy 服务器,它会开始监听本机的 2015 端口,并列出当前工作目录的内容。使用 http://localhost:2015 即可访问。如果能成功打开,或者可以看到一个 404 页面,那么说明 Caddy 安装成功了。

配置

Caddy 的所有配置都将被写到一个名为 Caddyfile 的文件中。点击这里阅读 Caddy 官方提供的入门指导,以及 Caddy 官方文档

在以下实例中,我们假定 Caddyfile 的位置是 /etc/caddy/Caddyfile,并且所有与 Caddy 相关的文件、目录,都存放于 /etc/caddy 下。

配置网站的地址

首先要配置 Caddy 所服务的网站的地址,如果只有一个地址的话,那么可以将地址写到 Caddyfile 的第一行,同时 Caddyfile 的第一行也必须是网站的地址。比如下面这样:

1
www.boris1993.tk

这样 Caddy 就会监听 www.boris1993.tk 所绑定的地址,并监听 80 端口提供 HTTP 服务,以及 443 端口提供 HTTPS 服务。在默认情况下,Caddy 会自动将 HTTP 请求使用 HTTP 301 返回码重定向到 HTTPS,除非显式配置禁用 HTTPS 服务。

如果需要指定端口号,那么可以在地址后面跟上端口号,比如 www.boris1993.tk:8080。因为我没有用到这项功能,所以没有测试过这样配置的效果。如果您有需要还请自行测试。

如果要同时开启多个网站,那么各个网站的配置需要以大括号包围起来,比如下面这样:

1
2
3
4
5
6
7
www.boris1993.tk {

}

www2.boris1993.tk {

}

我们这里就只演示仅有一个地址的情况。多个地址的配置与单个地址的配置方式相同,故不再赘述。

配置静态文件所在的位置并启用 gzip 压缩

有了地址之后,我们需要告诉 Caddy 要提供的静态文件在什么位置,这个可以使用 root 指令来制定,如下面这样:

1
2
3
www.boris1993.tk {
root /var/www
}

然后 Caddy 就会到 /var/www 目录寻找 index.html 等默认的主页文件。

启用 gzip 压缩,可以使我们的网站打开的更快。在 Caddy 中启用 gzip,也只需要一条指令:

1
2
3
4
www.boris1993.tk {
root /var/www
gzip
}

提供申请 HTTPS 证书的信息

在默认情况下,Caddy 会自动搞定申请 HTTPS 证书的事情,不需要用户进行干预。如果需要覆盖默认的配置,可以参考 Caddy 文档的 TLS 部分

配置日志

访问日志

网站的访问日志可以使用 log 指令来配置,该指令的文档可以参考这里

在这里我先放出我的配置,然后再逐行来解释。简明起见,我就只写出日志的部分,其余无关内容就不在这里写出来了。

1
2
3
4
5
6
log /   /var/log/caddy/access.log   "{combined}" {
rotate_size 1
rotate_age 7
rotate_keep 2
rotate_compress
}

第一行中,我指定要记录所有对网站根目录 / 的访问,将日志写到 /var/log/caddy/access.log 中,记录的方式是 combined

Caddy 提供了两种日志格式,commoncombinedcommon 是默认的记录格式。

common 的格式是这样子的:

{客户端IP地址} - {HTTP基础验证的用户名} [{访问时间}] \"{HTTP方式} {请求的URI} {协议版本}\" {HTTP状态码} {响应体的大小}

combined 格式,则是在 common 格式的末尾,追加如下内容:

\"{>Referer}\" \"{>User-Agent}\"

第二行 rotate_size 指定了在日志到达 1MB 大小之前不进行日志翻转,这个指令的单位是 MB

第三行 rotate_age 指定了保留 7 天的翻转日志。

第四行 rotate_keep 指定了只保留最近 2 个翻转日志,之前的版本将被删除。

第五行 rotate_compress 指定使用 gzip 压缩翻转日志。

错误日志

错误日志可以使用 errors 指令来配置,该指令的文档可以参考这里

同样,我将以我的配置作为范例来解释,如果需要其他的配置可以参考官方文档。

1
2
3
4
5
6
errors  /var/log/Caddy/error.log {
404 /var/www/error/HTTP404.html
rotate_age 7
rotate_keep 2
rotate_compress
}

第一行配置了错误日志将被写入到 /var/log/Caddy/error.log 中。

第二行配置了当发生 404 错误后显示的页面,这里还可以为其他错误码指定错误页面,语法参见官方文档。

其余三行的含义与上文 log 指令中对应参数的含义一致,不再赘述。

配置自动从 Git 拉取页面内容

Caddy 支持从一个指定的 Git 仓库克隆以及更新页面的内容到某个目录,并可以通过 WebHook 来监视仓库的更新,参考配置如下:

1
2
3
4
5
git https://github.com/boris1993/boris1993.github.io.git {
path /var/www
hook /hook hook.password
hook_type github
}

这里我配置 Caddy 从 https://github.com/boris1993/boris1993.github.io.git 这个仓库拉取静态页面文件,这就是本博客所在的 GitHub 仓库,拉去之后文件将被放到 /var/www 目录下。因为我要实现博客文件自动更新,所以这里的地址需要与 root 指令配置的位置相同。

hook 参数配置 Caddy 使用 www.boris1993.tk/hook 作为 WebHook 的监听地址,这个 hook 的访问密码是 hook.password,并且使用下一行中的 hook_type 指令显式指定 Hook 的类型是 github,也就是来自 GitHub 的 hook。

这样配置完毕后,还需要为远程 Git 仓库配置 hook,然后才可以实现自动更新。具体配置方式请参考 Git 仓库服务商的文档。

配置 Caddy 作为前置代理

一部分代理工具,比如 v2ray,支持使用一个 HTTP 服务器作为其前置代理,Caddy 就可以实现这样的功能。本示例中我配置 Caddy 作为 v2ray 的 WebSocket 代理,配置文件片段如下:

1
2
3
4
proxy /v2ray localhost:12345 {
websocket
header_upstream -Origin
}

这段配置指定了将 /v2ray 这个路径作为 localhost:12345 这个地址的前置代理,代理协议为 websocket。具体的配置方法请参考被代理程序的文档。

配置开机自启动

hook.service 插件可以一键生成 systemd 格式的自启动配置文件,只需要如下命令即可完成配置:

1
caddy -service install -conf /etc/caddy/Caddyfile

注意将 -conf 参数的值指向实际的 Caddyfile 的路径。

结束

至此,一个可以正常提供服务的 Caddy 服务器就配置完成了,现在 Caddy 可以提供正常的 HTTP 和 HTTPS 访问,并且会自动申请和续订 HTTPS 证书,在远端 Git 仓库有更新之后,Caddy 也会自动更新本地的文件,一切都变成了自动化操作,正常情况下完全可以实现无人值守运行。怎么样,是不是很方便?