在这篇文章里,我们将从零开始,用一台 Vultr 云主机,搭建一个能托管多个网站、自动签发 HTTPS、支持多后端负载均衡、可观测与健康检查的 Caddy Gateway 系统。

你将拥有一个真正意义上的"云上 Nginx 2.0",现代化、声明式、自动化。
🧭 一、目标与场景
假设你有以下三类服务:
| 类型 | 域名 | 服务说明 |
|---|---|---|
| 主站 | example.com |
Vue/React 静态网站 |
| API 服务 | api.example.com |
Flask 或 Node.js 服务 |
| 管理后台 | admin.example.com |
Vue + Express 组合项目 |
而你希望:
-
这三者全部使用 HTTPS;
-
通过一台网关统一反代;
-
后端容器可随时扩容;
-
有健康检查与负载均衡;
-
全部通过 Docker Compose 管理。
Caddy 就是最优解。
🏗️ 二、系统总体架构
flowchart LR
subgraph Internet
U[用户请求]
end
U -->|443/80| C[Caddy Gateway (Vultr云主机)]
C -->|/ -> 静态目录| FE[前端站点 (dist/)]
C -->|api.example.com ->| API1[App1容器]
C -->|admin.example.com ->| ADM1[Admin容器]
C -->|负载均衡| API2[App2容器]
说明:
-
所有请求先经过 Caddy;
-
按域名自动匹配;
-
静态站点由 Caddy 自行托管;
-
API 请求分发给多容器;
-
每个容器节点的健康状况自动检测。
🧱 三、环境准备
1️⃣ 创建 Vultr 实例
-
系统:Ubuntu 22.04
-
计划:1vCPU / 2GB 起步
-
网络:开启 IPv6(可选)
-
防火墙:放行 22、80、443
-
域名:提前设置好三条 A 记录
example.com → 实例IP api.example.com → 实例IP admin.example.com → 实例IP
2️⃣ 安装基础环境
登录云主机执行:
sudo apt update && sudo apt install -y docker.io docker-compose
sudo systemctl enable docker && sudo systemctl start docker
创建工作目录:
mkdir -p /opt/caddy-gateway && cd /opt/caddy-gateway
🧩 四、项目结构
/opt/caddy-gateway/
├─ docker-compose.yml
├─ Caddyfile
├─ site/
│ └─ index.html
├─ api/
│ ├─ Dockerfile
│ └─ app.py
└─ admin/
├─ Dockerfile
└─ app.py
🧰 五、后端与前端示例
/api/app.py
from flask import Flask, jsonify
import random
app = Flask(__name__)
@app.route("/health")
def health():
return jsonify(ok=True)
@app.route("/api/data")
def data():
return jsonify(source="API", value=random.randint(1,100))
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
/api/Dockerfile
FROM python:3.11-slim
WORKDIR /app
RUN pip install flask gunicorn
COPY app.py .
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
/admin/app.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/health")
def health():
return jsonify(status="ok", service="admin")
@app.route("/info")
def info():
return jsonify(role="Admin Panel", version="1.0")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7000)
/admin/Dockerfile
FROM python:3.11-slim
WORKDIR /app
RUN pip install flask gunicorn
COPY app.py .
CMD ["gunicorn", "-b", "0.0.0.0:7000", "app:app"]
/site/index.html
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Caddy Multi-Site</title></head>
<body>
<h1>Welcome to Caddy Gateway!</h1>
<p>主站托管成功 ✅</p>
</body>
</html>
🧩 六、Docker Compose:声明多服务 + 卷挂载
docker-compose.yml
version: "3.9"
services:
caddy:
image: caddy:2.8
container_name: caddy_gateway
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./site:/srv/www
- caddy_data:/data
- caddy_config:/config
- ./logs:/var/log/caddy
depends_on:
- api1
- api2
- admin
api1:
build: ./api
restart: unless-stopped
expose:
- "5000"
api2:
build: ./api
restart: unless-stopped
expose:
- "5000"
admin:
build: ./admin
restart: unless-stopped
expose:
- "7000"
volumes:
caddy_data:
caddy_config:
这里定义了:
-
api1、api2两个后端副本,用于负载均衡; -
admin独立服务; -
caddy负责反向代理和证书签发。
🧠 七、Caddyfile:多站点 + 负载均衡核心
Caddyfile
{
email admin@example.com
log {
output file /var/log/caddy/gateway.log
format json
}
}
# 主站
example.com {
root * /srv/www
file_server
encode gzip
respond /health 200
}
# API 站点 - 负载均衡
api.example.com {
encode gzip
reverse_proxy {
to api1:5000
to api2:5000
lb_policy round_robin
health_uri /health
health_interval 5s
health_timeout 2s
fail_duration 30s
}
respond /status 200
}
# 管理后台站点
admin.example.com {
reverse_proxy admin:7000
encode zstd
header {
X-Powered-By "Caddy Gateway"
}
}
🔍 解析关键点:
| 指令 | 作用 |
|---|---|
reverse_proxy |
启用反向代理功能 |
to |
定义后端目标地址(支持多个) |
lb_policy round_robin |
轮询负载均衡 |
health_uri /health |
健康检查路径 |
fail_duration 30s |
连续失败后的熔断时长 |
encode gzip zstd |
启用压缩传输 |
header |
添加自定义响应头 |
log |
全局 JSON 日志 |
🧪 八、启动与验证
在主目录执行:
docker compose up -d --build
查看服务:
docker ps
如果一切正常,你将看到:
caddy_gateway 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
api1
api2
admin
验证:
-
访问
https://example.com✅ -
访问
https://api.example.com/api/data✅ -
访问
https://admin.example.com/info✅
同时在 /var/log/caddy/gateway.log 可以看到结构化日志输出。
🧮 九、结果与负载均衡验证
用 curl 多次访问 API:
curl https://api.example.com/api/data
你会发现返回的随机数来源交替出现 ------ 来自不同后端容器。
查看健康检查:
docker logs caddy_gateway | grep health
如果某个后端宕机,Caddy 会自动跳过它,等待健康恢复再恢复转发。
🧱 十、进阶优化
✅ 支持 HTTP/3
Caddy 原生支持 QUIC 协议,只需开放 UDP 443:
sudo ufw allow 443/udp
✅ 启用防火墙与 Fail2Ban
防止暴力访问:
sudo apt install fail2ban
sudo ufw allow 22,80,443/tcp
✅ 统一日志采集
用 Fluent Bit / Vector 将 /var/log/caddy/gateway.log 发送到 Loki/Elasticsearch,实现全局监控。
✅ DNS-01 验证(通配符证书)
适用于 *.example.com:
{
acme_dns vultr {
api_token YOUR_VULTR_API_TOKEN
}
}
*.example.com {
reverse_proxy app:5000
}
📊 十一、性能与资源建议
| 实例类型 | 并发建议 | 说明 |
|---|---|---|
| 1c1g | 50--100 | 开发环境或轻量站点 |
| 2c2g | 500 | 单地区业务线 |
| 4c8g+ | 1k--5k | 企业级多域网关 |
| 负载均衡节点集群 | 横向扩展 | Vultr 负载均衡 + 多 Caddy 实例 |
你也可以让多台 Caddy 组成上层集群(通过 DNS 或 Vultr Load Balancer 实现)形成高可用入口。
🧩 十二、Caddy 与传统网关的差异
| 对比项 | Nginx | Caddy |
|---|---|---|
| HTTPS 管理 | 手动配置 | 自动申请与续签 |
| 路由配置 | 冗长复杂 | 声明式简洁 |
| 健康检查 | 需外部脚本 | 内置反代模块 |
| 日志格式 | 文本行 | JSON 结构化 |
| HTTP/3 支持 | 需编译 | 开箱即用 |
| 可扩展性 | 模块需编译 | 动态加载插件 |
| 学习曲线 | 高 | 极低 |
💡 十三、总结
这一整套方案让你在 Vultr 云上只用一条命令:
docker compose up -d
即可部署一台具备:
-
多站点反代;
-
自动 HTTPS;
-
负载均衡;
-
健康检查;
-
日志监控;
-
HTTP/3 支持;
的现代化 Web 网关。
这不只是"换掉 Nginx",
而是让部署、代理、证书、可观测,
都回归声明式自动化。
⚡ 一句话总结 :
Caddy 是面向开发者的"智能网关",Vultr 是面向工程师的"轻量云底座"。两者结合,就是云原生世界里最优雅的入口方案。
🧷 互动引导
如果这篇文章对你有帮助,请点个赞 ❤️
或收藏 📂 支持作者持续更新。
下期预告:
🔧《用 Caddy 构建全球 CDN 节点同步 + 智能路由系统(Vultr 多区域)》
敬请期待。