🚀 使用 Docker Compose 部署 Caddy(自动 HTTPS 服务器)
🚀 使用 Docker Compose 部署 Caddy
Caddy 是一款功能强大、扩展性高的 Web 服务器,采用 Go 语言编写,可用于静态资源托管和反向代理。它以其简洁的配置和自动 HTTPS 特性而闻名。
📝 项目简介
Caddy 是一个现代化的开源 Web 服务器,以其简洁的配置和强大的功能而受到开发者的青睐。
核心特点:
- 自动 HTTPS:Caddy 默认启用 HTTPS,并能自动从 Let's Encrypt 申请和更新 SSL 证书
- 简洁的配置:使用 Caddyfile 格式,配置比 Nginx 更加简单直观
- 无外部依赖:采用 Go 语言编写,编译为单个二进制文件,没有额外的运行时依赖
- HTTP/2 和 HTTP/3:原生支持 HTTP/2 和实验性 QUIC(HTTP/3) 支持
- 高度可扩展:可以通过插件系统扩展功能
- 内存安全:采用 Go 语言编写,内存安全更有保证
- 反向代理和负载均衡:内置反向代理和负载均衡功能
🔧 部署前准备
系统环境要求
- 操作系统:支持 Linux、Windows、macOS 等主流操作系统
- Docker 引擎:确保已安装 Docker 服务
- Docker Compose:确保已安装 Docker Compose
- 硬件资源:
- 内存:至少 512MB
- 存储空间:至少 1GB 可用空间
环境检查
-
检查 Docker 服务状态
bash systemctl status docker确保 Docker 服务处于active (running)状态 -
检查 Docker 版本
bash docker -v -
创建部署目录
bash mkdir -p /home/compose/caddy && cd /home/compose/caddy
⚙️ 配置 Docker Compose
准备配置文件
创建 docker-compose.yml 文件:
#version: "3.7"
services:
caddy:
image: caddy:latest # 官方最新镜像(自动包含 HTTPS 功能,无需额外插件)
restart: unless-stopped # 容器退出后自动重启(除非手动停止,保障服务稳定)
ports:
- "80:80" # 端口映射:主机 80 → 容器 80(HTTP 端口,证书验证必需)
- "443:443" # 端口映射:主机 443 → 容器 443(HTTPS 端口,加密访问必需)
volumes:
# 核心1:Caddy 配置文件(本地 ./Caddyfile → 容器 /etc/caddy/Caddyfile,修改规则需编辑此文件)
- ./Caddyfile:/etc/caddy/Caddyfile
# 核心2:证书与缓存目录(本地 ./data → 容器 /data,自动存储 SSL 证书、临时缓存)
- ./data:/data
# 核心3:运行时配置目录(本地 ./config → 容器 /config,自动生成,无需手动修改)
- ./config:/config
#cd /home/compose/caddy
#touch Caddyfile
创建 Caddy 配置文件:
touch Caddyfile
关键配置说明
- 镜像选择:使用官方
caddy:latest镜像 - 端口映射:
80:80:HTTP 端口443:443:HTTPS 端口- 数据持久化:
./Caddyfile:/etc/caddy/Caddyfile:Caddy 配置文件./data:/data:Caddy 数据目录,用于存储 SSL 证书等./config:/config:Caddy 配置目录- 重启策略:
unless-stopped确保容器自动重启
2. 步骤 2:编写 Caddyfile 基础配置(新手必学)
Caddyfile 是 Caddy 的核心配置文件,决定服务器 “如何处理请求”。以下提供 3 个常用场景的配置示例,新手可根据需求选择并修改:
场景 1:静态文件服务(搭建个人博客 / 静态网站)
将本地 ./html 目录作为网站根目录,访问域名即可查看静态文件(如 HTML、CSS、JS):
caddyfile
# Caddyfile 内容(替换 example.com 为你的域名)
example.com {
# 静态文件服务:指定网站根目录(容器内路径,需先在主机创建 ./html 目录并放入文件)
root * /usr/share/caddy/html
# 启用文件浏览(若目录无 index.html,显示文件列表,可选)
file_server browse
# 自动生成 index.html(若目录无此文件,可选)
try_files {path} /index.html
}
# 主机操作:创建 ./html 目录并放入测试文件
mkdir -p /home/compose/caddy/html
echo "<h1>Hello Caddy!</h1>" > /home/compose/caddy/html/index.html
# 同步修改 docker-compose.yml,添加 ./html 挂载(关键!否则容器无法访问静态文件)
# 在 volumes 中新增一行:- ./html:/usr/share/caddy/html
场景 2:反向代理(代理 Docker 容器服务,如 Nginx/Node.js)
将域名请求转发到本地其他服务(如 Docker 容器内的 3000 端口 Node.js 服务):
caddyfile
# Caddyfile 内容(替换 example.com 和 192.168.1.100:3000 为实际信息)
example.com {
# 反向代理:将所有请求转发到后端服务(192.168.1.100:3000 为后端服务地址)
reverse_proxy 192.168.1.100:3000
# 可选:启用压缩(减少传输流量,提升访问速度)
encode gzip
}
场景 3:纯 HTTP 服务(无需 HTTPS,适合内网测试)
内网环境无需 HTTPS,可直接用 HTTP 访问(需注释 HTTPS 相关配置,仅开放 80 端口):
caddyfile
# Caddyfile 内容(使用服务器内网 IP 或 localhost)
:80 { # 监听 80 端口,不指定域名(仅内网访问)
root * /usr/share/caddy/html
file_server
}
# 同时修改 docker-compose.yml,注释 443 端口映射(避免端口冲突)
# ports:
# - "80:80"
# # - "443:443"
3. 配置项关键说明(新手必看)
| 配置项 | 作用与注意事项 |
|---|---|
volumes: ./Caddyfile:/etc/caddy/Caddyfile |
必须挂载!修改 Caddyfile 后需重载配置(docker exec caddy caddy reload),无需重启容器。 |
volumes: ./data:/data |
核心目录!存储 Let's Encrypt 证书(删除会导致证书丢失,需重新申请),建议定期备份。 |
ports: 80:80 |
不可随意修改!Let's Encrypt 验证仅支持 80 端口,修改后证书申请失败。 |
Caddyfile 域名配置 |
若不指定域名(如 :80),Caddy 仅监听端口,不启用 HTTPS;指定域名则自动申请 HTTPS。 |
🚀 启动与验证
启动服务
docker compose up -d
验证服务状态
-
检查容器运行状态
bash docker ps应该看到 caddy 服务处于Up状态 -
查看服务日志
bash docker compose logs -f -
测试基本功能
bash curl http://localhost
(2)验证 HTTPS 功能(域名配置场景)
- 打开浏览器,输入你的域名(如
https://example.com); - 若地址栏显示 绿色锁标(表示 HTTPS 生效),且页面正常显示(如静态文件内容或反向代理服务),说明 HTTPS 配置成功;
- 进阶验证:执行
curl -I https://example.com,若输出HTTP/2 200和Strict-Transport-Security头,说明证书有效且启用 HTTP/2。
(3)验证静态 / 反向代理功能(对应场景)
- 静态文件服务:访问域名后显示
Hello Caddy!(或自定义 HTML 内容),说明静态文件加载正常; - 反向代理:访问域名后显示后端服务页面(如 Node.js 接口返回的 JSON 数据),说明转发正常。
🔌 基础配置与使用
Caddyfile 基础语法
Caddyfile 是 Caddy 的主要配置文件格式,语法简单直观:
# 静态文件服务器示例
:80 {
root * /usr/share/caddy
file_server
}
# 反向代理示例
:80 {
reverse_proxy /api/* http://backend:8080
}
# 启用文件浏览服务
:80 {
root * /usr/share/caddy
file_server browse
}
常见使用场景
-
静态文件服务器
example.com { root * /var/www file_server } -
反向代理
api.example.com { reverse_proxy http://localhost:3000 } -
PHP FastCGI 代理
example.com { root * /var/www php_fastcgi localhost:9000 file_server } -
重定向和重写
example.com { redir /old.html /new.html 301 rewrite /blog/* /blog.html{path} }
启用 HTTPS
Caddy 默认自动启用 HTTPS:
example.com {
root * /var/www
file_server
}
要禁用 HTTPS(开发环境):
localhost:80 {
root * /var/www
file_server
}
🛠️ 基础配置与使用2
Caddy 的核心是 Caddyfile 规则调整,以下补充常用操作,帮助新手扩展功能:
1. 重载配置(修改 Caddyfile 后)
修改 Caddyfile 后无需重启容器,执行以下命令重载配置(服务无中断):
# 进入 Caddy 容器执行重载命令
docker exec caddy caddy reload
# 若重载失败,查看错误原因(通常是 Caddyfile 语法错误)
docker exec caddy caddy validate # 验证 Caddyfile 语法
2. 多域名配置(一个 Caddy 服务处理多个域名)
在 Caddyfile 中添加多个域名块,实现多服务管理(如同时部署博客和 API):
# 域名1:静态博客(example.com)
example.com {
root * /usr/share/caddy/blog
file_server
}
# 域名2:API 服务(api.example.com,反向代理到 3000 端口)
api.example.com {
reverse_proxy 192.168.1.100:3000
encode gzip
}
- 注意:需为每个域名配置 DNS 解析(A 记录指向服务器 IP),Caddy 会自动为每个域名申请 HTTPS 证书。
3. 自定义 SSL 证书(不用 Let's Encrypt)
若需使用自签证书或第三方证书,将证书文件放入 ./data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/ 目录,或在 Caddyfile 中指定证书路径:
example.com {
# 指定自定义证书(容器内路径,需将证书挂载到容器)
tls /etc/caddy/certs/example.com.crt /etc/caddy/certs/example.com.key
reverse_proxy 192.168.1.100:3000
}
# 同时修改 docker-compose.yml,挂载证书目录:
# volumes:
# - ./certs:/etc/caddy/certs # 本地 ./certs 存放自定义证书
🛠️ 维护与管理
日常维护操作
- 服务启停 ```bash # 停止服务 docker compose down
# 启动服务 docker compose up -d
# 重启服务 docker compose restart ```
-
配置重载
bash # 修改 Caddyfile 后重新加载 docker compose exec caddy caddy reload -
查看配置
bash docker compose exec caddy caddy adapt --config /etc/caddy/Caddyfile
备份与恢复
- 备份配置和数据
tar -czf caddy-backup-$(date +%Y%m%d).tar.gz ./Caddyfile ./data ./config
- 恢复备份
tar -xzf caddy-backup-YYYYMMDD.tar.gz
docker compose restart
版本更新
# 拉取最新镜像并重启
docker compose pull
docker compose down
docker compose up -d
注意:建议定期更新到最新稳定版本,以避免已知问题。
🐛 常见问题排查
1. 容器启动失败
问题现象:docker ps 显示容器状态不是 Up
解决方案:
- 检查日志:docker compose logs
- 验证端口占用:netstat -tulpn | grep -E ':80|:443'
- 检查 Caddyfile 语法:docker compose exec caddy caddy validate --config /etc/caddy/Caddyfile
2. HTTPS 证书申请失败
问题现象:Let's Encrypt 证书申请失败
解决方案: - 确保域名解析正确 - 检查防火墙设置,确保 80 和 443 端口可访问 - 验证域名所有权
3. 静态文件无法访问
问题现象:404 错误或权限拒绝
解决方案:
- 检查 root 指令配置的路径是否正确
- 确保文件权限正确
- 验证文件路径大小写
4. 反向代理连接失败
问题现象:502 Bad Gateway
解决方案: - 检查后端服务是否运行 - 验证代理目标地址和端口 - 检查网络连接
5. 配置修改不生效
问题现象:Caddyfile 更改后未生效
解决方案:
- 重新加载配置:docker compose exec caddy caddy reload
- 检查配置语法:docker compose exec caddy caddy validate --config /etc/caddy/Caddyfile
- 重启服务:docker compose restart
6. 性能问题
问题现象:响应缓慢或内存占用高
解决方案: - 检查服务器资源使用情况 - 优化 Caddyfile 配置 - 考虑启用缓存或调整超时设置
通过本教程,您应该已经成功部署并配置了 Caddy Web 服务器。Caddy 的简洁配置和自动 HTTPS 特性使其成为传统 Web 服务器的优秀替代品。如果在使用过程中遇到其他问题,可以参考 Caddy 官方文档或社区支持资源。
🐛 常见问题排查2
1. HTTPS 证书申请失败(日志提示 “acme: error”)
-
原因 1:域名未解析到服务器 IP 或解析未生效(DNS 缓存问题)。解决:通过
ping example.com验证域名是否指向正确 IP,若解析错误,修改域名服务商的 A 记录;若解析正确,等待 10-30 分钟(DNS 缓存生效)后重启 Caddy。 -
原因 2:80 端口被防火墙 / 安全组阻止(Let's Encrypt 需通过 80 端口验证域名所有权)。解决:开放 80 端口(
sudo ufw allow 80/tcp),云服务器需在安全组添加 “允许 80 端口入站” 规则。 -
原因 3:服务器无外网访问(无法连接 Let's Encrypt 服务器)。解决:检查服务器网络(
ping 8.8.8.8),确保能访问外网,若使用代理,需在Caddyfile中配置代理(参考 Caddy 官方文档)。
2. 端口 80/443 被占用(启动提示 “port is already allocated”)
- 原因:其他服务(如 Nginx、Apache)已占用 80/443 端口。
- 解决: 1.查看占用进程:
# 查看 80 端口占用
sudo lsof -i :80
# 查看 443 端口占用
sudo lsof -i :443
2.停止占用服务(如 Nginx):
sudo systemctl stop nginx
3.重启 Caddy 容器:docker compose up -d。
3. 静态文件服务 404 错误(页面提示 “Not Found”)
-
原因 1:
Caddyfile中root路径与容器内实际路径不一致(如未挂载静态文件目录)。解决:确认docker-compose.yml已挂载静态文件目录(如- ./html:/usr/share/caddy/html),且Caddyfile中root * /usr/share/caddy/html路径正确。 -
原因 2:静态文件目录权限不足(容器无法读取文件)。解决:执行
sudo chmod -R 777 ./html,赋予静态文件目录读写权限。
4. 反向代理 502 错误(页面提示 “Bad Gateway”)
-
原因 1:后端服务未启动或地址错误(如 IP / 端口填写错误)。解决:确认后端服务(如 Node.js)已启动,且地址(如
192.168.1.100:3000)可访问(通过curl 192.168.1.100:3000测试)。 -
原因 2:容器网络问题(Caddy 容器无法访问后端服务)。解决:若后端服务也是 Docker 容器,建议将两者加入同一网络(在
docker-compose.yml中配置networks),用容器名作为地址(如reverse_proxy backend:3000,backend为后端容器名)。
通过以上步骤,新手可快速搭建 Caddy 服务器并实现 HTTPS 访问、静态文件服务或反向代理功能。Caddy 配置灵活且维护成本低,是个人与企业部署 Web 服务的优选工具。如需探索更多功能(如负载均衡、API 网关),可参考 Caddy 官方文档。