Skip to content

🚀 使用 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 可用空间

环境检查

  1. 检查 Docker 服务状态 bash systemctl status docker 确保 Docker 服务处于 active (running) 状态

  2. 检查 Docker 版本 bash docker -v

  3. 创建部署目录 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

关键配置说明

  1. 镜像选择:使用官方 caddy:latest 镜像
  2. 端口映射
  3. 80:80:HTTP 端口
  4. 443:443:HTTPS 端口
  5. 数据持久化
  6. ./Caddyfile:/etc/caddy/Caddyfile:Caddy 配置文件
  7. ./data:/data:Caddy 数据目录,用于存储 SSL 证书等
  8. ./config:/config:Caddy 配置目录
  9. 重启策略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

验证服务状态

  1. 检查容器运行状态 bash docker ps 应该看到 caddy 服务处于 Up 状态

  2. 查看服务日志 bash docker compose logs -f

  3. 测试基本功能 bash curl http://localhost


(2)验证 HTTPS 功能(域名配置场景)

  1. 打开浏览器,输入你的域名(如 https://example.com);
  2. 若地址栏显示 绿色锁标(表示 HTTPS 生效),且页面正常显示(如静态文件内容或反向代理服务),说明 HTTPS 配置成功;
  3. 进阶验证:执行 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
}

常见使用场景

  1. 静态文件服务器 example.com { root * /var/www file_server }

  2. 反向代理 api.example.com { reverse_proxy http://localhost:3000 }

  3. PHP FastCGI 代理 example.com { root * /var/www php_fastcgi localhost:9000 file_server }

  4. 重定向和重写 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 存放自定义证书

🛠️ 维护与管理

日常维护操作

  1. 服务启停 ```bash # 停止服务 docker compose down

# 启动服务 docker compose up -d

# 重启服务 docker compose restart ```

  1. 配置重载 bash # 修改 Caddyfile 后重新加载 docker compose exec caddy caddy reload

  2. 查看配置 bash docker compose exec caddy caddy adapt --config /etc/caddy/Caddyfile

备份与恢复

  1. 备份配置和数据
   tar -czf caddy-backup-$(date +%Y%m%d).tar.gz ./Caddyfile ./data ./config
  1. 恢复备份
   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”)

  • 原因 1Caddyfile 中 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:3000backend 为后端容器名)。

通过以上步骤,新手可快速搭建 Caddy 服务器并实现 HTTPS 访问、静态文件服务或反向代理功能。Caddy 配置灵活且维护成本低,是个人与企业部署 Web 服务的优选工具。如需探索更多功能(如负载均衡、API 网关),可参考 Caddy 官方文档