# nginx-cerbot **Repository Path**: jsonlee_lee/nginx-cerbot ## Basic Information - **Project Name**: nginx-cerbot - **Description**: No description available - **Primary Language**: Shell - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-10 - **Last Updated**: 2026-03-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Encrypt 使用 Docker Compose 部署 Certbot + Nginx,自动申请和续期 Let's Encrypt SSL 证书。 ## 特性 - **多域名支持** — 在 `domains.conf` 中集中配置所有域名 - **自动续期** — Certbot 容器每 12 小时检查并续期证书 - **自动重载** — Nginx 容器每 6 小时重载配置,加载新证书 - **分阶段部署** — 先 HTTP 引导,再申请证书,最后启用 HTTPS - **域名独立配置** — 每个域名生成独立的 Nginx 配置文件,单个域名失败不影响其他域名 ## 前提条件 - Docker 和 Docker Compose v2 - 服务器的 80 和 443 端口可公网访问 - 域名的 DNS A/AAAA 记录已指向服务器 ## 项目结构 ``` encrypt/ ├── docker-compose.yml # Nginx + Certbot 服务定义 ├── domains.conf # 域名与上游服务的映射 ├── nginx/ │ ├── nginx.conf # Nginx 主配置 │ ├── conf.d/ # 自动生成的域名配置(不要手动编辑) │ └── templates/ │ ├── http.conf.template # HTTP 引导模板(仅 ACME challenge) │ └── ssl.conf.template # 完整 HTTP+HTTPS 模板 └── scripts/ └── init-ssl.sh # 首次证书申请脚本 ``` ## 快速开始 ### 1. 配置域名 编辑 `domains.conf`,填入域名和对应的上游服务: ``` api.example.com app:3000 www.example.com web:8080 admin.example.com admin:4000 ``` 每行将一个公网域名映射到 `gateway` 网络上的 Docker 服务和端口。 ### 2. 接入应用服务 上游应用服务需要加入 `gateway` 网络。在应用的 `docker-compose.yml` 中: ```yaml services: app: image: your-app networks: - gateway networks: gateway: external: true ``` ### 3. 使用 Staging 环境测试 首次务必使用 Let's Encrypt 的 staging 环境,避免触发速率限制: ```bash ./scripts/init-ssl.sh you@example.com --staging ``` 确认以下几点: - 80 端口 HTTP 正常响应 - 证书已签发(浏览器会显示不受信任,staging 环境正常现象) - HTTPS 能正确代理到上游服务 ### 4. 申请正式证书 staging 验证通过后,去掉 `--staging` 参数正式申请: ```bash ./scripts/init-ssl.sh you@example.com ``` ### 5. 完成 服务栈已运行。Certbot 会自动续期证书,无需配置 cron 或其他宿主机定时任务。 ## 工作原理 ### 首次证书申请 (`init-ssl.sh`) 脚本对每个域名执行分阶段部署: 1. 生成 HTTP-only 的 Nginx 配置(用于响应 ACME challenge) 2. 启动 Nginx 监听 80 端口 3. 运行 `certbot certonly --webroot`,通过 HTTP-01 验证域名所有权 4. 生成完整的 SSL Nginx 配置(HTTPS 终止 + 反向代理) 5. 重载 Nginx 并启动完整服务栈 ### 自动续期 初始化完成后,两个容器各自运行内部循环: | 容器 | 循环 | 作用 | |------|------|------| | Certbot | 每 12h 执行 `certbot renew` | 续期即将过期的证书 | | Nginx | 每 6h 执行 `nginx -s reload` | 加载续期后的新证书 | 不需要宿主机的 cron 或 systemd timer。 ## 新增域名 1. 在 `domains.conf` 中添加域名: ``` new.example.com new-service:8080 ``` 2. 将 DNS 指向服务器 3. 重新运行初始化脚本: ```bash ./scripts/init-ssl.sh you@example.com ``` 已有的证书会被保留 — Certbot 会跳过仍然有效的域名。 ## 故障排查 ### 证书申请失败 - **DNS**:确认 `dig +short your-domain.com` 返回服务器 IP - **防火墙**:确认 80 和 443 端口已开放(云安全组、宿主机防火墙等) - **Nginx 日志**:`docker compose logs nginx` - **Certbot 日志**:查看 `init-ssl.sh` 输出或 `docker compose logs certbot` ### 续期后 HTTPS 未更新 Nginx 每 6 小时自动重载。如需立即生效: ```bash docker compose exec nginx nginx -s reload ``` ### 速率限制 Let's Encrypt 对正式环境有[速率限制](https://letsencrypt.org/docs/rate-limits/)。务必先用 `--staging` 测试。触发限制后需等待一段时间才能重试。 ### 查看证书信息 ```bash echo | openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | openssl x509 -noout -dates -subject ``` ## 数据卷 | 卷 | 用途 | 需要备份? | |----|------|-----------| | `certbot-webroot` | ACME challenge 文件(临时) | 否 | | `certbot-certs` | 证书、私钥、续期元数据 | **是** | 请备份 `certbot-certs` 卷,避免数据丢失后需要重新申请证书。 ## 限制 - **不支持泛域名证书** — 仅通过 HTTP-01 验证申请具体域名证书 - **单机部署** — 不适用于多节点或负载均衡场景 - **不自动生成 Nginx 配置** — 新增域名后需重新运行 `init-ssl.sh` ## License MIT