2020注:Caddy更新了2.0版本,本篇内容可能不再适用。2.0博主尝试过变化较大但依然比较好用,有空会在本文更新。
用过比较长时间的 Nginx,总感觉那种复杂的配置文件很不舒服,每次要去实现一个反代一个转发都要去搜索教程。在没有找到好用的图形化管理工具的条件下还是比较困难。
正巧找到了一个基于 Golang 的 Web 服务器 Caddy 。相比 nginx.conf
,Caddy 的配置文件相当简洁,多站点配置、反向代理等功能可以全部在一个 Caddyfile
文件里配置。官方有一个 28秒创建一个 HTTPS 服务器。
除此之外,Caddy 还有很多 优点:
- 单文件,无依赖
- 默认支持 https,支持自动签发 Let’s Encrypt 证书
- 默认支持 HTTP/2
- 丰富的插件系统,可以快速配置缓存、CORS、自动拉取 Git 仓库、Markdown 支持、ip/地区过滤等十分强大的功能
安装与运行
以下操作以 Debian 9 x64 为例。
在 Download 页面选择系统与所需插件,下载到 tar.gz 文件,将解压出来的 caddy
文件放在 /usr/local/bin
或其他 PATH 目录下,就安装完成了。
tar -xzf caddy*.tar.gz caddy
mv ./caddy /usr/local/bin
caddy
默认情况下,Caddy 启动了 2015
端口,在浏览器访问 ip:2015
可以看到 404 Not Found(Caddy 没有生成欢迎页面),说明启动成功。
要实现自定义配置,在含有 Caddyfile 的文件夹下运行 caddy
,就可以自动读取配置并启动服务器。
Caddyfile 配置
Caddy 的配置文件简单粗暴。要创建一个 https 的站点,只需要给 tls 传入邮箱,Caddy 就可以自动申请证书,并实现 http 自动跳转到 https:
website.com {
gzip
tls [email protected]
}
指定网站目录
要指定网站目录,使用 root 指令:
website.com {
gzip
tls [email protected]
root /www/website.com
}
反向代理
要实现反向代理,需要 proxy
:
abc.website.com {
gzip
tls [email protected]
root /www/website.com
proxy / http://127.0.0.1:8360 {
transparent
}
}
自动拉取 Git 仓库
需要安装 http.git 插件。文档:http.git
Git 命令可以让 Caddy 定时拉取仓库中的最新版本
git [repo path] {
repo repo # 仓库地址
path path # 拉取到的本地路径,默认为网站根目录
branch branch # 拉取的分支,默认为 master。
key key # SSH私钥的路径;只有私库才需要。
interval interval # 每次拉取的时间间隔(s),默认为 3600
clone_args args # 调用 git clone 命令时附加的参数
pull_args args # 调用 git pull 命令时附加的参数
hook /webhook secret-password # 开启 Webhook,支持 GitHub, Gitlab, BitBucket, Travis, Gogs, Gitee.
hook_type type # 要使用的 webhook 类型。默认情况下会自动检测 webhook 类型
then command [args...] # 成功拉取后执行的命令
then_long command [args...] # 成功拉取后执行的命令(后台)
}
例如,配置一个 ljl.li
站点,自动拉取 Github 中的对应仓库,并开启 webhook 实现仓库有 commit 时自动拉取代码:
ljl.li {
tls [email protected]
gzip
root /home/wwwroot/ddiu8081.github.io
git {
repo https://github.com/ddiu8081/ddiu8081.github.io.git
hook /webhook ddiu8081
}
}
启动 Caddy,可以看到已经成功拉到了代码:
现在,Caddy 已经可以帮我们每小时拉一遍代码。然后去 Github Webhooks 配置,填入 url 和 secret,实现主动推送:
Markdown 渲染
Caddy 提供一种 Markdown 渲染功能。
markdown [basepath] {
ext extensions... # 要渲染的文件扩展名列表,空格分隔,默认为.md .markdown .mdown
[css|js] file # 指定包含在页面中的 css 与 js 文件。
template [name] path # 指定 Markdown 模板。
templatedir defaultpath # Markdown 模板的默认路径。
}
这是一个示例模板:
<!DOCTYPE html>
<html>
<head>
<title>{{.Doc.title}}</title>
</head>
<body>
Welcome to {{.Doc.sitename}}!
<br><br>
{{.Doc.body}}
</body>
</html>
多站点
要实现多站点配置,只需要把各站点配置并列在一起:
website1.com {
gzip
tls [email protected]
root /www/website1.com
log ../access.log # 开启访问日志
}
localhost:8080, website2.com, website3.com { # 一个配置可以运用在多个站点
gzip
tls [email protected]
root /www/website2.com
}
更多 Caddyfile 配置可以参考 官网 Doc 。
开机自启
使用 systemd 将 Caddy 注册为服务。
sudo curl -s https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service -o /etc/systemd/system/caddy.service # 下载 systemd 配置文件
按照 caddy.service
文件创建对应目录 /etc/caddy
、 /etc/ssl/caddy
。
sudo mkdir /etc/caddy
sudo chown -R root:www-data /etc/caddy
sudo touch /etc/caddy/Caddyfile # Caddy 配置文件
sudo mkdir /etc/ssl/caddy
sudo chown -R www-data:root /etc/ssl/caddy
sudo chmod 0770 /etc/ssl/caddy
允许 Caddy 绑定低级别端口:
setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy
最后保存配置。
sudo systemctl daemon-reload # 重载配置
sudo systemctl enable caddy.service # 开启自启动
可能遇到的问题:
如果 Caddy 服务没有成功启动,查看访问日志:
journalctl --boot -u caddy.service
Unable to access root path '/home/…'
:无法访问网站目录。从 /etc/systemd/system/caddy.service
关闭对 /home
文件夹的保护,将 ProtectHome
改为 false。
; Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
ProtectHome=true
listen tcp :443: bind: permission denied
:无法绑定端口,使用 setcap
命令允许对敏感端口的访问。
总结
相比 Nginx 与 Apache,Caddy 配置非常友好,对于一些简单的网站需求来说足够了。在不过多苛求性能的情况下,或许你也可以试试 Caddy。
参考
[1] Caddy Quick Start - Tutorial