在构建现代 Web 服务时,HTTPS 已经是不可或缺的标准。传统上配置 Nginx + Let’s Encrypt 虽然强大,但配置过程相对繁琐,还需要单独设置定时任务来续签证书。
今天我们要介绍的主角是 Caddy。它是一个用 Go 语言编写的现代化 Web 服务器,最大的亮点就是开箱即用、默认支持自动申请和续签 HTTPS 证书。本文将带大家通过 Docker Compose 部署 Caddy,并创建一个独立的 Docker 网络,方便后续扩展其他 Web 服务。
为什么选择 Caddy + 独立网络?
- 全自动 HTTPS:只需在配置文件中写下你的域名,Caddy 会自动搞定证书申请(Let’s Encrypt / ZeroSSL)与续签。
- 配置极其简单:核心配置文件(Caddyfile)通常只需要寥寥几行。
- 独立网络(
web_network):创建一个外部持久网络。后续新部署的容器(如 WordPress、Node.js 应用等)只要加入这个网络,Caddy 就能直接通过容器名反向代理它们,无需暴露任何多余的宿主机端口,安全且优雅。
部署步骤
第一步:创建自定义 Docker 网络
首先,我们在终端中创建一个名为 web_network 的外部网络:
Bash
docker network create web_network
为什么要单独创建? > 默认情况下,Docker Compose 会为每个项目创建独立的隔离网络。通过手动创建外部网络,可以让不同的
docker-compose.yml项目互联互通。
第二步:准备项目目录与文件
在服务器上创建工作目录(例如 ~/caddy-proxy):
Bash
mkdir -p ~/caddy-proxy && cd ~/caddy-proxy
mkdir data config
data/:用于持久化 Caddy 申请到的 SSL 证书和密钥(非常重要,避免容器重启后重复申请触发速率限制)。config/:用于存放 Caddy 的运行配置状态。
第三步:编写 Caddyfile
在当前目录下创建 Caddyfile,这是 Caddy 的核心配置文件:
Nginx
# 你的域名,Caddy 会自动为此域名申请 HTTPS 证书
yourdomain.com {
# 反向代理到同网络下的另一个容器(这里以一个虚拟的 backend 容器为例)
reverse_proxy backend_service:8080
}
# 示例:以后扩展新服务,直接追加即可
# app.yourdomain.com {
# reverse_proxy node_app:3000
# }
💡 请将
yourdomain.com替换为您自己的真实域名,并确保该域名的 DNS 解析已经指向了你当前服务器的公网 IP。
第四步:编写 docker-compose.yml
创建 docker-compose.yml 文件,将 Caddy 容器化,并连接到我们刚创建的 web_network:
YAML
version: '3.8'
services:
caddy:
image: caddy:2-alpine
container_name: caddy_proxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # 启用 HTTP/3 支持
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./data:/data
- ./config:/config
networks:
- web_network
networks:
# 声明使用外部预先创建好的网络
web_network:
external: true
第五步:启动 Caddy
一切就绪后,一键启动容器:
Bash
docker-compose up -d
你可以通过查看日志来确认 Caddy 是否成功申请了证书:
Bash
docker-compose logs -f
如果看到 certificate obtained successfully 类似的字样,恭喜你,你的域名已经成功开启了 HTTPS!
如何接入新服务
既然我们搭建好了这个网关,后续如果有新的 Web 应用(比如一个 Python 后端应用),该如何通过 Caddy 暴露出去呢?
你只需要在新应用的 docker-compose.yml 中做两件事:
- 将容器加入
web_network。 - 为容器指定一个固定的
container_name(或使用服务名)。
新应用示例 (~/my-app/docker-compose.yml):
YAML
version: '3.8'
services:
my_web_app:
image: nginx:alpine
container_name: backend_service # 对应 Caddyfile 中的名字
# 注意:这里不需要映射 80 端口到宿主机,保持安全
networks:
- web_network
networks:
web_network:
external: true
启动新应用后,修改 Caddy 的 Caddyfile,然后执行 docker-compose exec -w /etc/caddy caddy caddy reload 热重载配置,即可实现无缝扩展!
总结
通过 Docker Compose 配合独立网络 web_network,我们用极其简练的代码搭建起了一个强大的 HTTPS 反向代理网关。Caddy 帮我们省去了折腾证书的烦恼,而独立网络则让后续的微服务扩展变得像拼乐高一样简单。