之所以不用 nginx 了,是因为它配置和使用真的没有 caddy 简单方便。
官网为: caddyserver 商业网/
$ brew install caddy
$ brew services start caddy
$ sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
$ 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
其他架构可以前往官网查看安装命令
Caddy 的配置文件有两种,一种是 JSON 格式的(字段太多,不想用),一种是 Caddyfile 文件,里面配置很简单
新建文件 Caddyfile 输入内容
PLAINTEXT
:8080
respond "Hello, caddy!"
现在在这个配置文件目录下执行 caddy run 就会默认使用这个配置文件启动,接着访问 http://localhost:8080 就能看到网页了
配置文件除了上面那样写,还可以在域名后面跟 {},把这个网站的配置包裹住,尤其是同时写多个网站的配置的时候(多个网站的时候地址必须唯一,不能多次指向同一个地址)
示例:
PLAINTEXT
# Caddyfile 配置文件中,这个是注释,和 Nginx 配置文件一样
test.vonne.me {
respond "Welcome!"
}
:8080, :8090 {
respond "Hello"
}
localhost {
respond "80"
}
我已经将 test.vonne.me 解析到了服务器的 IP
执行 caddy run 将会自动为域名 test.vonne.me 申请 SSL 证书,之后就可以直接访问 https://test.vonne.me 了
注意:如果服务器已经有其他 web 服务了,例如 Nginx,有可能 80 和 443 端口都被占用了,这个时候需要先停止其他 web 服务,再重新执行 caddy run 命令
我觉得自动申请证书和简单配置就能使用,这两点就已经足够让我替换掉 Nginx 了
通过上面的示例,已经知道怎么配置它了,但是我们需要的是让他能够处理网页,而不是单纯返回一个字符串
我们可以先尝试通过运行命令的方式启动一个文件服务器,它可以托管一个静态网站、把你的文件共享在网络上
SH
$ caddy file-server --root ~/mysite --listen :2015 --browse
可以不带参数,就默认以当前目录为站点,但可能监听不了低端口
如果使用配置文件的话,例如新建 /etc/caddy/Caddyfile,内容为
PLAINTEXT
localhost:2015 {
root * ~/mysite
file_server browse
}
需要在其他目录运行,则可以添加 --config 参数指定配置文件路径,例如 caddy run --config /etc/caddy/Caddyfile 这样就会以这个配置文件启动一个文件服务器
模版页面
如果在 HTML 中使用了模版语法({{}})那么就可以在配置文件中添加 templates,例如 HTML 文件中使用了
HTML
Page loaded at: {{now | date "Mon Jan 2 15:04:05 MST 2006"}}
那么配置文件可以写成
PLAINTEXT
localhost:2015 {
root * ~/mysite
templates
file_server
}
如果是使用的命令,则多加一个 --templates 参数
启用 Gzip 和 Zstandard 支持
PLAINTEXT
localhost:2015 {
root * ~/mysite
encode zstd gzip
templates
file_server
}
例如把 www 域名重定向到 @
PLAINTEXT
www.domain.com {
redir https://domain.com{uri} permanent
}
domain.com {
root * /data/www
file_server
}
这里 {} 包裹的是占位符,{uri} 等价于 {http.request.uri},是通用资源符
加上了 permanent 就是 301 永久重定向
使用命令
SH
$ caddy reverse-proxy --from :2080 --to :9000
省略 --from,就是默认的 localhost,如果 http 就是 80 端口,https 就是 443 端口
SH
$ caddy reverse-proxy --to :9000
其他域名
SH
$ caddy reverse-proxy --from example.com --to https://example.com:9000
如果两个主机名不同,则需要加参数
SH
$ caddy reverse-proxy --from example.com --to https://localhost:9000 --change-host-header
使用的 Caddyfile 配置
PLAINTEXT
localhost
reverse_proxy :9000
如果反代的只是某个路径下的,就可以使用匹配器令牌,例如只匹配 api/ 下的
PLAINTEXT
yourdomain.com {
reverse_proxy /api/* 127.0.0.1:9000
}
除了上面这种,还可以这样写
PLAINTEXT
yourdomain.com {
reverse_proxy /api/* {
to 127.0.0.1:9000
}
}
例如
PLAINTEXT
yourdomain.com {
reverse_proxy /api/* {
to 127.0.0.1:9000 127.0.0.1:9001 127.0.0.1:9002
}
}
负载均衡策略(调度方式)默认是随机的,我们可以通过 lb_policy 来指定不同的负载均衡策略
例如
PLAINTEXT
yourdomain.com {
reverse_proxy /api/* 127.0.0.1:9000 127.0.0.1:9001 127.0.0.1:9002 {
lb_policy round_robin
}
}
使用 lb_try_duration 5s 设定重试等待时间为 5s,lb_try_interval 250ms 默认的重试时间间隔 250 毫秒
PLAINTEXT
example.com {
root * /root/www/admin
try_files {path} {file} /index.html
file_server
encode gzip
}
PLAINTEXT
https://example.com {
reverse_proxy /path http://localhost:54321 {
header_up Host {http.reverse_proxy.upstream.hostport}
header_down Access-Control-Allow-Headers *
header_down Access-Control-Allow-Origin *
}
}
先拉取镜像到本地,然后再运行这个镜像
$ docker pull caddy
由于大多时候都连不上官方仓库,所以使用镜像加速
$ docker pull hub.vonne.me/caddy
创建 Caddyfile
PLAINTEXT
http:// {
root * /srv/www/localhost/
file_server
}
创建 sites/localhost/index.html
PLAINTEXT
Hello, I'm in Docker.
之后直接运行(没用镜像就不需要前面的 hub.vonne.me/)
$ docker run --name caddyweb -d -p 80:80 -p 443:443 -p 443:443/udp \
-v $PWD/Caddyfile:/etc/caddy/Caddyfile \
-v ./sites/:/srv/www/ \
-v caddy_data/:/data/ \
-v caddy_config:/config/ \
hub.vonne.me/caddy
配置参数
或者编写 docker-compose.yml,这样可以同时启动多个服务(services 下可以放更多服务,例如 redis、ruby 等)
YAML
services:
caddyweb:
image: hub.vonne.me/caddy
restart: unless-stopped
ports:
- '80:80'
- '443:443'
- '443:443/udp'
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./sites/:/srv/www/
- caddy_data/:/data/
- caddy_config:/config/
volumes:
caddy-data:
external: true
caddy-config:
然后执行命令 dcoker-compose up -d 启动
需要执行 caddy 相关的命令,可以先进入容器的终端
SH
$ docker exec -it 容器名或id sh
然后在正常执行 caddy 命令,例如 caddy reload
新建 Dockerfile 文件
PLAINTEXT
FROM node:18 as builder
# Create work directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY ./web/package.json /usr/src/app/package.json
RUN apk upgrade --update-cache --available
RUN npm install yarn --legacy-peer-deps
RUN yarn install --silent
COPY ./web /usr/src/app
RUN yarn run build
# ====== RUN CADDY =======
FROM caddy:2.8
COPY Caddyfile /etc/caddy/Caddyfile
COPY --from=builder /usr/src/app/build /srv/www
运行命令
SH
$ docker build -t myweb:1 .
$ docker run --name myweb -d -p 80:80 -p 443:443 -p 443:443/udp myweb:1
在启动 caddy 的时候你可能注意到它下面的日志
SH
$ caddy run
2024/10/29 05:30:29.168 INFO using adjacent Caddyfile
2024/10/29 05:30:29.173 INFO admin admin endpoint started {"address": "localhost:2019", "enforce_origin": false, "origins": ["//[::1]:2019", "//127.0.0.1:2019", "//localhost:2019"]}
它会启动一个管理地址,你可以通过它对 Caddy 进行管理(默认端口号为 2019)
有一些 API 可供使用,例如下面两个

