Vultr × Caddy 多站点反向代理 + 负载均衡网关系统实战
在这篇文章里,我们将从零开始,用一台 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 randomapp = 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.8container_name: caddy_gatewayrestart: unless-stoppedports:- "80:80"- "443:443"volumes:- ./Caddyfile:/etc/caddy/Caddyfile:ro- ./site:/srv/www- caddy_data:/data- caddy_config:/config- ./logs:/var/log/caddydepends_on:- api1- api2- adminapi1:build: ./apirestart: unless-stoppedexpose:- "5000"api2:build: ./apirestart: unless-stoppedexpose:- "5000"admin:build: ./adminrestart: unless-stoppedexpose:- "7000"volumes:caddy_data:caddy_config:
这里定义了:
api1、api2两个后端副本,用于负载均衡;admin独立服务;caddy负责反向代理和证书签发。
🧠 七、Caddyfile:多站点 + 负载均衡核心
Caddyfile
{email admin@example.comlog {output file /var/log/caddy/gateway.logformat json}
}# 主站
example.com {root * /srv/wwwfile_serverencode gziprespond /health 200
}# API 站点 - 负载均衡
api.example.com {encode gzipreverse_proxy {to api1:5000to api2:5000lb_policy round_robinhealth_uri /healthhealth_interval 5shealth_timeout 2sfail_duration 30s}respond /status 200
}# 管理后台站点
admin.example.com {reverse_proxy admin:7000encode zstdheader {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 多区域)》
敬请期待。
