1. 为什么选择Caddy+Docker Compose方案
在单机服务器环境下部署HTTPS服务时,传统方案需要手动配置Nginx/Apache、申请证书、设置自动续期,整个过程繁琐且容易出错。而Caddy作为新一代Web服务器,内置自动HTTPS功能,配合Docker Compose的容器编排能力,可以实现"开箱即用"的HTTPS服务部署。
我三年前开始在生产环境使用这套组合,最直观的感受是:原先需要半天完成的HTTPS配置工作,现在只需15分钟就能搞定。更重要的是,证书自动续期这个最容易出问题的环节,Caddy已经完美解决了。
2. 环境准备与工具选型
2.1 基础环境要求
- 一台Linux服务器(推荐Ubuntu 20.04+)
- 已安装Docker和Docker Compose
- 域名解析已指向服务器IP
- 开放80和443端口
注意:如果使用云服务器,记得在安全组规则中放行80/443端口。我曾在阿里云上排查了半小时才发现是安全组没配置。
2.2 为什么选择这些工具
- Caddy:相比Nginx的复杂配置,Caddy的Caddyfile语法更简洁,自动HTTPS功能基于Let's Encrypt实现,无需额外配置
- Docker Compose:通过声明式配置管理多个容器,特别适合单机多服务的场景
- 容器化部署:避免污染主机环境,方便迁移和版本控制
3. 核心配置解析
3.1 Docker Compose文件编写
创建docker-compose.yml文件:
yaml复制version: '3'
services:
caddy:
image: caddy:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./data/caddy:/data
- ./config/caddy:/config
environment:
- ACME_AGREE=true
关键参数说明:
volumes挂载说明:/data:存储证书数据(必须持久化)/config:Caddy运行时配置Caddyfile:我们的主配置文件
ACME_AGREE:自动同意Let's Encrypt服务条款
3.2 Caddyfile配置示例
基础配置(Caddyfile文件):
code复制example.com {
reverse_proxy your-app:8080
}
高级配置示例:
code复制{
email your@email.com # 用于证书通知
}
api.example.com {
encode gzip
reverse_proxy backend:8000 {
header_up X-Real-IP {remote_host}
}
}
static.example.com {
root * /var/www
file_server
}
4. 完整部署流程
4.1 初始化步骤
- 创建目录结构:
bash复制mkdir -p {data/caddy,config/caddy}
- 编写
Caddyfile后启动服务:
bash复制docker-compose up -d
- 验证容器状态:
bash复制docker-compose logs -f
4.2 证书管理机制
Caddy的证书管理流程:
- 首次访问时自动申请证书
- 证书存储在
/data/caddy目录 - 自动监控证书有效期(默认30天续期)
- 通过ACME协议完成验证
实测发现:证书续期过程对服务零影响,这是比Certbot方案更优雅的地方
5. 常见问题排查
5.1 证书申请失败
可能原因及解决方案:
| 现象 | 排查步骤 | 解决方法 |
|---|---|---|
| 连接超时 | 检查80端口是否开放 | telnet your-domain 80 |
| 域名解析错误 | 检查DNS记录 | dig +short your-domain |
| 权限问题 | 检查挂载目录权限 | chown -R 1000:1000 ./data |
5.2 性能调优建议
在高并发场景下建议:
Caddyfile复制{
acme_ca https://acme-v02.api.letsencrypt.org/directory
ocsp_stapling off
}
your-domain.com {
reverse_proxy your-app:8080 {
transport http {
dial_timeout 10s
}
}
}
6. 进阶使用技巧
6.1 多站点配置
通过单个Caddy实例支持多个域名:
code复制domain1.com {
redir https://www.domain1.com{uri}
}
www.domain1.com {
handle_path /api/* {
reverse_proxy api-service:3000
}
handle {
reverse_proxy web-service:8080
}
}
domain2.com {
root * /srv/domain2
file_server
}
6.2 与后端服务集成
与PHP应用的配合示例:
code复制app.example.com {
root * /var/www/public
php_fastcgi php-fpm:9000
file_server
}
7. 安全加固措施
7.1 基础安全配置
推荐在Caddyfile中添加:
code复制{
security {
frame_deny
referrer_policy strict-origin-when-cross-origin
ssl_stapling
}
}
your-domain.com {
header {
X-XSS-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
}
}
7.2 访问控制示例
限制管理后台访问:
code复制admin.example.com {
@admin {
path /admin/*
not remote_ip 192.168.1.0/24
}
respond @admin 403
}
8. 监控与维护
8.1 日志收集方案
修改docker-compose.yml添加日志驱动:
yaml复制services:
caddy:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
8.2 健康检查配置
Caddy内置的/metrics端点:
code复制your-domain.com {
metrics /metrics
reverse_proxy node-exporter:9100
}
9. 迁移与备份策略
9.1 关键数据备份
需要定期备份的目录:
./data/caddy(证书存储)./config/caddy(自动生成的配置文件)Caddyfile(主配置文件)
建议备份命令:
bash复制tar -czvf caddy-backup-$(date +%Y%m%d).tar.gz {data/caddy,config/caddy,Caddyfile}
9.2 跨服务器迁移
迁移步骤:
- 在新服务器安装Docker环境
- 复制docker-compose.yml和Caddyfile
- 恢复备份的数据目录
- 启动服务
10. 性能对比测试
在2核4G的云服务器上实测结果:
| 指标 | Caddy | Nginx + Certbot |
|---|---|---|
| 首次HTTPS部署时间 | 2分钟 | 15分钟 |
| 证书续期影响 | 无感知 | 需要重启服务 |
| 静态文件QPS | 12,000 | 13,500 |
| 内存占用 | 45MB | 35MB |
虽然Nginx在极限性能上略有优势,但Caddy的易用性和自动化程度更适合中小型项目。