- HTTP/1.1 和 HTTP/2
- 同时接受 HTTPS 自动签发和手动管理
- 虚拟主机 (多个站点工作在单个端口上)
- 原生 IPv4 和 IPv6 支持
- 静态文件分发
- 平滑重启/重载
- 反向代理 (HTTP 或 WebSocket)
- 负载均衡和健康性检查
- Markdown 渲染
- 文件浏览服务
- 等等
用Docker快速搭一个HTTPS站点
快速实现HTTPS
# 当前目录有一个配置文件 Caddyfile
vim Caddyfile
tooltt.com
# 一行命令启动
docker run -d --name caddy \
-p 80:80 \
-p 443:443 \
-v $(pwd)/Caddyfile:/etc/Caddyfile \
abiosoft/caddy
docker run -p 80:80 -p 443:443 --name caddy \
-v /mydata/caddy/Caddyfile:/etc/caddy/Caddyfile \
-v /mydata/caddy/data:/data \
-v /mydata/caddy/site:/srv \
-d caddy
安装为系统服务
系统环境:Ubuntu 20.04 LTS
Caddy 可以作为一个系统服务安装,命令:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
:::tips
注意:这种方式安装完成后会启动服务,开机自动启动。:::
还可以下载一个可执行文件使用。- 下载地址:https://caddyserver.com/download
- 在网页上方选择自己的操作系统后,点击右侧蓝色的 Download 按钮即可
- 下载好的文件不能够直接运行,需要为其添加权限
命令行执行
$ mv caddy_linux_amd64 caddy # 将下载后的文件重命名方便后面指令输入,根据系统不同文件名不一样
$ sudo chmod a+x caddy # 为 Caddy 添加可执行权限
$ mv caddy /bin/caddy # 将 Caddy 复制到 bin 目录这样可以在命令行随时使用
<font style="color:rgb(239, 112, 96);">caddy version</font>
命令,出现版本信息:
即为安装成功!
v2.4.6 h1:HGkGICFGvyrodcqOOclHKfvJC0qTU7vny/7FhYp9hNw=
从零完成 HTTPS 站点
域名设置生效,返回如下:
curl "https://cloudflare-dns.com/dns-query?name=caddy.hellogithub.com&type=A" -H "accept: application/dns-json"
第三步:创建配置文件 Caddyfile,无需额外的开启 HTTPS 的设置:
{"Status":0,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"caddy.hellogithub.com","type":1}],"Answer":[{"name":"caddy.hellogithub.com","type":1,"TTL":592,"data":"107.150.122.176"}]}
caddy.hellogithub.com
respond "Hello HTTPS!"
- 域名
- 访问返回的内容
sudo caddy run
常用命令
配置文件
Caddy 的原生配置文件使用的是 JSON 格式。但是为了用户编写方便它提供了 Caddyfile 作为接口让用户可以快速配置站点信息,运行时 Caddy 会自动将 Caddyfile 的配置信息转为 JSON 配置文件。 Caddyfile 所能提供功能不如 JSON 配置文件强大,但是对于不需要复杂配置的用户而言完全够用了。 Caddyfile 的配置指令格式如下:Caddyfile 的文件结构如图所示:
directive [<matcher>] <args...> { # matcher 代表匹配器,如果提供则该指令将只对 matcher 描述的资源进行响应
subdirective [<args...>] # 子指令
}
下表是对应的关键字和解释,对照上图学习可以加深理解。
关键字 | 解释 | 使用 |
---|---|---|
Global options block | 服务器全局配置 | 可用于配置是否启用HTTPS和Admin API等 |
Snippet | 可以复用的配置片段 | 定义好后认可以通过import 关键字引用 |
Site Block | 单个网站配置 | 通过file_server 可以配置静态代理,通过reverse_proxy 可以配置动态代理 |
Matcher definition | 匹配定义 | 默认情况下指令会产生全局影响,通过它可以指定影响范围 |
Comment | 注释 | 使用# 符号开头 |
Site address | 网站地址 | 默认使用HTTPS,如需开启HTTP,需要指定http:// 开头 |
Directive | 指令 | 指令赋予了Caddy强大的功能 |
演示
下面将演示如何用 Caddy 搭建站点,加深理解配置格式和命令使用。 目录结构:两个页面文件 index.html 和 HG.html 的内容如下:
.
├── Caddyfile
├── index.html
└── public
└── HG.html
Caddyfile 配置内容如下:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
你好,世界!
</body>
</html>
<!-- HG.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HelloGitHub</title>
</head>
<body>
HelloGitHub
</body>
</html>
在当前目录输入:
# 如果本机没有 wordpress 则注释这一块儿的站点配置
#:80 { # 部署一个 wordpress 站点
# root * /var/www/wordpress
# php_fastcgi unix//run/php/php-version-fpm.sock # 配置一个 fastcig 服务
# file_server # 配置一个文件服务
#}
http://localhost:3000 {
basicauth /public/* {
# 匹配访问 localhost:3000/public/* 的请求,为其加上登陆保护
HG JDJhJDE0JGEySk9janFMdHlBY2Y0aVdQZklQak9HcmwzNDZhNFg0N3V5Ny9EZkZMZHB1Nkt4ZE5BNGJt
# 用户名 HG 密码 HelloGitHub,密码使用 caddy hash-passowrd 指令生成
}
root * ./ # 设置当前站点根目录为当前文件夹,* 表示匹配所有的 request
templates
file_server {
# 配置当前站点为静态文件服务器,可用于博客系统的搭建
hide .git # 隐藏所有的 .git 文件
}
}
:4000 {
reverse_proxy /public/* http://localhost:3000 # 配置反向代理
# 只会匹配 locahost:4000/public 的请求,转发到 localhost:3000/public/
}
最后,效果如下:
$ caddy run # 启动 Caddy
- 访问:http://localhost:3000 可以看到页面展示 “你好,世界!”
- 访问:http://localhost:3000/public/HG.html 提示输入用户名和密码,验证正确后才能看到页面。
- 访问:http://localhost:4000 则会自动跳转到端口 3000 的页面
Caddy的使用
静态代理
<font style="color:rgb(40, 202, 113);background-color:rgb(251, 249, 253);">静态代理</font>
就是将请求代理到静态资源上去,这里对<font style="color:rgb(40, 202, 113);background-color:rgb(251, 249, 253);">localhost</font>
的请求代理到前端项目中。
- 将前端项目上传到
<font style="color:rgb(40, 202, 113);">/srv</font>
目录下; - 然后修改Caddyfile中的配置,再使用
<font style="color:rgb(40, 202, 113);">caddy reload</font>
命令重启下Caddy服务;
http://localhost {
root * /srv/mall
file_server browse
}
动态代理
<font style="color:rgb(40, 202, 113);background-color:rgb(251, 249, 253);">动态代理</font>
就是把代理服务器的请求转发到另一个服务上去,这里把对<font style="color:rgb(40, 202, 113);background-color:rgb(251, 249, 253);">api.localhost</font>
的请求代理到演示环境的API服务上去。
- 然后修改Caddyfile中的配置,再使用
<font style="color:rgb(40, 202, 113);">caddy reload</font>
命令重启下Caddy服务;
http://api.localhost {
reverse_proxy http://admin-api.localhost
}
按目录划分
有时候需要通过同一个域名的不同子目录来访问不同的前端项目,比如通过<font style="color:rgb(40, 202, 113);background-color:rgb(251, 249, 253);">/admin</font>
目录访问后台管理系统,通过<font style="color:rgb(40, 202, 113);background-color:rgb(251, 249, 253);">/app</font>
目录访问前台系统。
- 此时可以对目录进行如下划分;
mall.localhost/admin #访问mall后台管理系统
mall.localhost/app #访问mall前台商城系统
- 这里先把前端项目上传到
<font style="color:rgb(40, 202, 113);">/srv/</font>
目录下; - 修改Caddyfile中的配置,然后重启下Caddy容器;
http://mall.localhost {
route /admin/* {
uri strip_prefix /admin
file_server {
root /srv/admin
}
}
route /app/* {
uri strip_prefix /app
file_server {
root /srv/app
}
}
}
文件压缩
如果服务器带宽比较低,网站访问速度会很慢,这时可以通过让Caddy开启Gzip压缩来提高网站的访问速度。
修改Caddyfile中的配置,使用<font style="color:rgb(40, 202, 113);">encode</font>
指令开启Gzip压缩,修改完成后重启Caddy服务;
http://mall.localhost {
root * /srv/mall
encode {
gzip
}
file_server browse
}
地址重写
有的时候网站更换了域名,但还有用户在使用老的域名访问,这时可以通过Caddy的地址重写功能来让用户跳转到新的域名进行访问。
修改Caddyfile中的配置,使用<font style="color:rgb(40, 202, 113);">redir</font>
指令重写地址,修改完成后重启Caddy服务;
http://mall.localhost {
redir https://www.localhost
}
接口管理方式
Caddy 除了简单易懂的配置文件方式,还提供了管理配置的接口。通过这些接口可以轻松实现 Web 服务器管理自动化、集成发布等高级功能。- POST /load 设置或替换活动配置
- POST /stop 停止活动配置并退出进程
- GET /config/[path] 导出指定路径的配置
- POST /config/[path] 设置或替换对象;追加到数组
- PUT /config/[path] 创建新对象或插入数组
- PATCH /config/[path] 替换现有对象或数组元素
- DELETE /config/[path] 删除指定路径的值
- 在 JSON 中使用@id 轻松遍历配置结构
- GET /reverse_proxy/upstreams 返回配置的代理上游的当前状态