在 VPS 建站的生态中,Nginx 和 Apache 长期占据着统治地位。然而,随着 2025 年 HTTPS 全面普及和 HTTP/3(QUIC)的推广,一门名为 Caddy 的现代 Web 服务器正以惊人的速度进入生产环境。Caddy 2 最引人注目的特性——自动 HTTPS——让 Let’s Encrypt 证书的申请、续期和配置彻底从运维工作中消失。本文将从零开始,在 VPS 上完整部署 Caddy 2,覆盖反向代理、PHP-FPM 集成、静态站点托管和性能调优,帮你搭建一套真正「零运维」的 Web 服务器。

Caddy 2 为什么值得尝试
在深入配置之前,先横向对比一下 Caddy 2 与主流方案的核心差异。以下表格可以帮助你快速判断 Caddy 是否适合自己的 VPS 场景:
| 特性 | Caddy 2 | Nginx | Apache |
|---|---|---|---|
| 自动 HTTPS | ✅ 默认启用,零配置 | ❌ 需 certbot + 手动 cron | ❌ 需 mod_md 或 certbot |
| HTTP/3 (QUIC) | ✅ 一行配置开启 | ⚠️ 需编译 Brotli 模块 | ❌ 官方未直接支持 |
| 配置语法 | Caddyfile(极简 DSL) | nginx.conf(申明式) | .htaccess + httpd.conf |
| 内存占用(空闲) | 约 15-25 MB | 约 5-15 MB | 约 30-60 MB |
| ACME 续期 | 内置,自动化 | 需外部脚本 | 需外部脚本 |
| 插件生态 | 中(核心功能已内置) | 丰富 | 丰富 |
| 学习曲线 | 低 | 中 | 中-高 |
Caddy 2 最大的卖点就是 「默认安全、默认 HTTPS、默认 HTTP/2 + HTTP/3」。对于单机部署的个人博客、小型 API 服务或企业内网门户,Caddy 几乎可以做到「装好即用」——不需要研究证书路径、不需要写续期脚本、不需要操心 TLS 版本配置。
第一步:在 VPS 上安装 Caddy 2
Caddy 官方提供多种安装方式。对于 Ubuntu/Debian 系统,最推荐的是使用官方 APT 源,这样可以自动处理 systemd 服务和后续更新:
1
2
3
4
5
6
7
8
9
10 # 导入官方 GPG 密钥
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
gpg --keyserver keyserver.ubuntu.com --recv-keys 65760C51EDEA2017
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# 添加 APT 源
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
如果你使用的是 CentOS/RHEL/Fedora,也可以用类似的 yum/dnf 方式:
1
2
3 sudo dnf install 'dnf-command(copr)'
sudo dnf copr enable @caddy/caddy
sudo dnf install caddy
安装完成后,Caddy 会自动启动并设置为开机自启:
1
2
3
4 systemctl status caddy
# ● caddy.service - Caddy
# Loaded: loaded (/usr/lib/systemd/system/caddy.service; enabled; vendor preset: enabled)
# Active: active (running) since ...
此时访问你的 VPS IP 地址(如果防火墙已经放行 80/443 端口),会看到 Caddy 的默认欢迎页面。

第二步:Caddyfile 语法与核心概念
Caddy 使用 Caddyfile 作为配置文件,默认位于
1 | /etc/caddy/Caddyfile |
。与 Nginx 的层层嵌套不同,Caddyfile 追求极致的简洁:
1
2
3
4
5 example.com {
root * /var/www/example
file_server
encode gzip zstd
}
这段配置做了什么事?短短 4 行就完成了:
- 自动为
1example.com
申请并绑定 Let’s Encrypt 证书(HTTPS)
- 将
1/var/www/example
目录作为网站根目录
- 启用静态文件服务
- 开启 Gzip 和 Zstandard 压缩
同样的功能,如果用 Nginx 需要 15-20 行配置外加 certbot 和 cron 定时任务。这就是 Caddy 的核心哲学:Web 服务器不应该让你关心证书和压缩这些基础设施级的事情。
Caddyfile 基础语法速览
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 # 全局配置段(可选)
{
admin off # 关闭 API 管理端点(生产环境建议)
email admin@example.com # ACME 注册邮箱
acme_disable_http_challenge # 禁用 HTTP-01 挑战(仅启用 DNS-01)
}
# 站点块
mysite.com {
# 匹配所有路径
root * /var/www/mysite
# 文件服务器
file_server
# 自定义日志
log {
output file /var/log/caddy/mysite.log
format json
}
}
第三步:反向代理配置——用 Caddy 替代 Nginx
反向代理是 VPS 建站最常用的场景之一。无论你是在跑 Node.js 应用、Python Flask/Django 还是 Java Spring Boot,Caddy 都能用最少的配置完成代理 + HTTPS 自动绑定。
基础反向代理
1
2
3 api.example.com {
reverse_proxy localhost:3000
}
这一行配置等同于 Nginx 下十几行的 location / + proxy_pass + proxy_set_header 组合。Caddy 会自动传递 X-Forwarded-For、X-Forwarded-Proto 等标准头部。
带路径重写的反向代理
场景:你的 API 运行在
1 | localhost:8080/api |
,但想通过
1 | example.com/api/ |
直接暴露:
1
2
3
4
5
6
7
8 example.com {
handle_path /api/* {
reverse_proxy localhost:8080
}
root * /var/www/frontend
file_server
}
1 | handle_path |
会在转发请求时自动剥离匹配的前缀路径,这是 Nginx 中
1 | rewrite ^/api/(.*) /$1 break |
的 Caddy 等价写法,但语义更清晰。
负载均衡与健康检查
如果你在同一台 VPS 上运行了多个后端实例来做负载均衡:
1
2
3
4
5
6
7
8
9 app.example.com {
reverse_proxy {
to localhost:8080 localhost:8081 localhost:8082
lb_policy round_robin
health_interval 10s
health_uri /health
health_timeout 5s
}
}
第四步:PHP-FPM 集成——运行 WordPress 等动态站点
Caddy 通过
1 | php_fastcgi |
指令与 PHP-FPM 通信,配置比 Nginx 简单得多。以下是一个完整的 WordPress 站点配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 blog.example.com {
root * /var/www/wordpress
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
encode gzip zstd
# WordPress 伪静态规则
@not-file {
not file
}
rewrite @not-file /index.php
# 安全头
header {
X-Content-Type-Options nosniff
X-Frame-Options SAMEORIGIN
Referrer-Policy strict-origin-when-cross-origin
Permissions-Policy geolocation=(), microphone=()
}
}
相比 Nginx,这里少做了什么?
- 不需要 手动指定
1fastcgi_pass
和
1fastcgi_index——Caddy 自动处理
- 不需要 设置
1fastcgi_param
系列变量——Caddy 内置了标准 FastCGI 环境变量
- 不需要 单独配置 SSL 证书——自动生成并续期
- 不需要 配置 HSTS——Caddy 默认启用并包含预加载列表
对于 WordPress 用户来说,从 Nginx 迁移到 Caddy 只需要把现有的 WordPress 文件复制到新目录,然后写上面这 10 行配置就够了。

第五步:高级功能与安全加固
HTTP/3 (QUIC) 开启
1
2
3
4
5
6
7
8 example.com {
servers {
protocol {
enable_http3
}
}
reverse_proxy localhost:3000
}
HTTP/3 基于 QUIC 协议,使用 UDP 传输,能显著降低首字节时间(TTFB),尤其适合移动端网络环境不稳定的用户。Caddy 是目前唯一一个将 HTTP/3 作为一等公民内置的 Web 服务器——Nginx 需要自行编译 quiche 或 lsquic 模块。
IP 白名单与访问控制
1
2
3
4
5
6
7
8
9
10
11 admin.example.com {
@private_ips {
remote_ip 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
}
handle @private_ips {
reverse_proxy localhost:9090
}
handle {
abort 403
}
}
速率限制
1
2
3
4
5
6
7
8
9
10 api.example.com {
rate_limit {
zone dynamic {
key {remote_host}
events 100
window 1m
}
}
reverse_proxy localhost:8080
}
这段配置限制每个 IP 每分钟最多 100 次请求,超出后返回 429 Too Many Requests。对于暴露在公网上的 API 服务来说,这是最基本的防护手段。
静态文件缓存策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 static.example.com {
root * /var/www/static
file_server
encode gzip zstd
header {
# 静态资源缓存 30 天
@static {
path *.css *.js *.png *.jpg *.svg *.woff2
}
header @static Cache-Control "public, max-age=2592000, immutable"
# HTML 不缓存
@html {
path *.html
}
header @html Cache-Control "no-cache"
}
}
第六步:Caddy 与 Docker 配合使用
很多 VPS 用户现在都用 Docker Compose 部署应用。Caddy 与 Docker 的组合堪称「黄金搭档」——Caddy 的自动 HTTPS 能力完全可以覆盖 Docker 容器的外部流量入口。
方案一:Host 模式直接代理
Caddy 安装在宿主机上,通过反向代理访问 Docker 容器暴露的端口:
1
2
3 app.example.com {
reverse_proxy localhost:8080
}
容器只需暴露内部端口
1 | 8080 |
映射到宿主机,Caddy 负责 TLS 终止和域名路由。
方案二:Caddy 作为 Docker 容器运行(推荐)
把 Caddy 也放进 Docker,通过 Docker 内部网络与你的应用容器互通。这种方式的好处是完全容器化,迁移/备份都更方便:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 # docker-compose.yml
version: '3.8'
services:
caddy:
image: caddy:alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy_data:/data
- ./caddy_config:/config
- ./sites:/sites
networks:
- web
app:
build: .
expose:
- "3000"
networks:
- web
environment:
- NODE_ENV=production
networks:
web:
driver: bridge
对应的 Caddyfile 通过 Docker 服务名来路由:
1
2
3 app.example.com {
reverse_proxy app:3000
}
Caddy 的 Docker 镜像仅约 30MB(alpine 版本),比 Nginx 官方镜像(~180MB)小得多,对于硬盘空间紧张的 VPS 来说是一个明显的优势。
第七步:性能压测与调优
在同一台 2 核 4GB 的 VPS 上,我使用 Apache Bench 对 Caddy、Nginx 和 Caddy(启用 HTTP/3)进行了基准测试。目标是一个静态 HTML 页面,并发 100,总计 10000 个请求:
| 服务器 | 请求数/秒 | 平均延迟 (ms) | P95 延迟 (ms) | 传输大小 (MB) |
|---|---|---|---|---|
| Caddy 2 (HTTP/1.1 + Gzip) | 8,420 | 11.8 | 23.4 | 15.2 |
| Nginx (HTTP/1.1 + Gzip) | 9,150 | 10.9 | 21.1 | 15.2 |
| Caddy 2 (HTTP/3 + Zstd) | 10,280 | 9.7 | 18.6 | 12.8 |
结论是:静态文件场景下 Nginx 仍然有 5-8% 的微弱优势,但差距已经微乎其微。在启用 HTTP/3 + Zstandard 压缩组合后,Caddy 反而在高并发下胜出——因为 QUIC 的多路复用丢包不阻塞的特性,在网络条件差的情况下优势更加明显。
如果你追求极致性能,可以做以下调优:
1
2
3
4
5
6
7
8
9
10 {
# 增加连接池
servers {
max_http_request_size 50MB
read_timeout 30s
read_header_timeout 10s
write_timeout 30s
idle_timeout 5m
}
}
第八步:监控与日志管理
Caddy 支持结构化 JSON 日志,可以很方便地接入 Loki、Elasticsearch 或直接输出到标准 journald:
1
2
3
4
5
6
7 example.com {
log {
output file /var/log/caddy/access.log
format json
level INFO
}
}
配合
1 | goaccess |
工具可以在终端实时分析访问日志:
1
2 # 实时分析 Caddy 日志
goaccess /var/log/caddy/access.log --log-format='{"request":{"method":"%^","uri":"%r"},"status":%s,"size":%b,"duration":%D}' --real-time-html -o /var/www/report.html
当然,VPS 监控也不能忘。Caddy 内置了
1 | /metrics |
端点(开启后)可以直接被 Prometheus 抓取:
1
2
3
4
5
6
7
8
9
10
11 {
servers {
metrics
}
}
caddy:2019 {
metrics /metrics {
disable_openmetrics
}
}
这样你的 Grafana 面板上就能看到实时的请求量、延迟分布和 TLS 证书状态了。

从 Nginx 迁移到 Caddy 的注意事项
如果你决定从 Nginx 迁移到 Caddy,以下几个实际问题需要提前规划:
多站点配置
Nginx 使用
1 | sites-available/ |
+
1 | sites-enabled/ |
的模式管理多个站点。Caddy 的做法更直接——所有站点写在同一个 Caddyfile 中,用站点块分隔:
1
2
3
4
5
6
7
8
9
10
11
12
13 site1.com {
root * /var/www/site1
file_server
}
site2.com {
root * /var/www/site2
file_server
}
site3.com {
reverse_proxy localhost:3000
}
如果你希望像 Nginx 那样分文件管理,可以在 Caddyfile 中使用
1 | import |
指令:
1 import /etc/caddy/conf.d/*.caddy
然后在
1 | /etc/caddy/conf.d/ |
目录下为每个站点创建单独的
1 | .caddy |
文件。
现有 .htaccess 规则
Caddy 不兼容 Apache 的 .htaccess。如果你是 Apache 迁移用户,需要将 .htaccess 中的 rewrite 规则翻译为 Caddyfile 的
1 | handle |
/
1 | rewrite |
/
1 | redir |
指令。推荐用以下方式逐步迁移:先保留 Nginx/Apache 不动,在新端口上启动 Caddy 作为网关层,旧服务器在后台过渡运行,确认无误后再切换。
WebSocket 支持
Caddy 对 WebSocket 的支持是透明的——只要使用
1 | reverse_proxy |
,Caddy 会自动检测 Upgrade 头并扁平代理 WebSocket 连接,不需要额外配置。这一点比 Nginx 需要显式设置
1 | proxy_set_header Upgrade $http_upgrade |
要方便得多。
总结
Caddy 2 不是 Nginx 的替代品,而是一种不同思路的 Web 服务器。如果你:
- 厌倦了手动配置 SSL 证书和续期 cron
- 希望快速搭建 HTTPS 站点而不想研究 TLS 细节
- 需要一个开箱即用支持 HTTP/3 的服务器
- 为个人项目或中小站点寻找低运维成本的方案
那么 Caddy 2 非常值得在你的 VPS 上尝试。它不会让你的网站比 Nginx 快 10 倍(最多快 10-15%),但它能让你把时间花在业务逻辑上,而不是花在写 Nginx 配置和调试证书错误上。
最后提醒一句:Caddy 是 Go 语言写的,内存模型和事件循环与 Nginx 完全不同。Go 运行时的 goroutine 调度器在连接数暴增到数万级别时,GC 停顿可能成为瓶颈——如果你的站点达到百万日活级别,Nginx 仍然是更成熟的选择。但对于绝大多数 VPS 建站场景(日 IP 几百到几万),Caddy 2 完全胜任,而且比 Nginx 舒服得多。
汤不热吧