# nginx-certbot **Repository Path**: doughface/nginx-certbot ## Basic Information - **Project Name**: nginx-certbot - **Description**: 把nginx和certbot打包在一起,实现自动申请、更新证书 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-01 - **Last Updated**: 2026-04-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Nginx + Certbot Docker 方案 基于 Nginx 1.29.7 官方镜像,集成 Certbot 实现 SSL 证书自动申请和续期,支持多域名动态管理。 ## 功能特性 - ✅ 基于 nginx:1.29.7 官方镜像 - ✅ 完整保留 Nginx 官方镜像所有功能 - ✅ 集成 Certbot 自动申请 Let's Encrypt 证书 - ✅ 自动续期证书(可配置检查周期) - ✅ **支持多域名独立管理** - ✅ **支持动态添加新域名** - ✅ **每个域名独立证书** - ✅ 支持静态文件服务和反向代理 - ✅ 支持测试环境和生产环境 - ✅ Docker Compose 一键部署 - ✅ **sites-enabled 自定义配置持久化,重新生成不覆盖** ## 快速开始 ### 1. 配置环境变量 编辑 `docker-compose.yml` 中的环境变量: ```yaml environment: - CERT_CHECK_INTERVAL=12 # 证书检查周期(小时) - EMAIL=admin@example.com # Let's Encrypt 邮箱 - STAGING=0 # 0=生产环境,1=测试环境 ``` ### 2. 配置域名 在 `domains/` 目录下创建域名配置文件,每个域名一个文件: **静态网站示例** (`domains/example.com.conf`): ```bash PRIMARY_DOMAIN="example.com" ALIAS_DOMAINS="www.example.com" ENABLE_SSL="true" ROOT_DIR="/usr/share/nginx/html" ``` **反向代理示例** (`domains/api.example.com.conf`): ```bash PRIMARY_DOMAIN="api.example.com" ALIAS_DOMAINS="" ENABLE_SSL="true" BACKEND_URL="http://backend:3000" ``` ### 3. 启动服务 ```bash # 首次启动(建议先用测试环境) docker-compose up -d # 查看日志 docker-compose logs -f ``` ### 4. 动态添加新域名 **方法一:使用脚本** ```bash # 添加静态网站 ./add-domain.sh blog.example.com www.blog.example.com # 添加反向代理 ./add-domain.sh api.example.com '' http://backend:8080 # 重启容器 docker-compose restart ``` **方法二:手动创建配置** 1. 在 `domains/` 目录创建 `新域名.conf` 文件 2. 重启容器:`docker-compose restart` 3. 证书将自动申请(每小时检查一次新域名) ## 目录结构 ``` nginx-certbot/ ├── Dockerfile # 镜像构建文件 ├── docker-compose.yml # Docker Compose 编排 ├── add-domain.sh # 添加域名脚本 ├── scripts/ │ ├── entrypoint.sh # 容器启动脚本 │ ├── init-certs.sh # 证书初始化脚本 │ ├── renew-certs.sh # 证书续期脚本 │ ├── check-new-domains.sh # 新域名检查脚本 │ ├── generate-nginx-config.sh # Nginx 配置生成脚本 │ └── test-generate-nginx-config.sh # 配置生成测试脚本 ├── nginx/ │ ├── nginx.conf # Nginx 主配置 │ └── sites-enabled/ # 自动生成的站点配置 ├── domains/ # 域名配置目录(手动管理) │ ├── example.com.conf # 域名配置示例 │ └── api.example.com.conf # API 域名配置示例 ├── certbot/ │ ├── conf/ # Let's Encrypt 证书存储 │ ├── www/ # ACME 验证目录 │ └── logs/ # 证书日志 └── www/ # 网站内容目录 └── index.html ``` ## 域名配置说明 每个域名配置文件支持以下参数: ```bash # 主域名(必填,用于证书申请) PRIMARY_DOMAIN="example.com" # 别名域名(可选,逗号分隔,会添加到同一个证书中) ALIAS_DOMAINS="www.example.com,blog.example.com" # 是否启用 SSL(true/false) ENABLE_SSL="true" # 反向代理地址(可选,与 ROOT_DIR 二选一) BACKEND_URL="http://backend:8080" # 静态文件根目录(可选,与 BACKEND_URL 二选一) ROOT_DIR="/usr/share/nginx/html" ``` ## 工作原理 ### 证书管理流程 1. **容器启动时**: - 读取 `domains/` 目录下所有域名配置 - 为每个域名生成 Nginx 配置文件 - 检查并申请缺失的证书 2. **定时任务**: - 每 N 小时检查证书续期(可配置) - 每小时检查新添加的域名并自动申请证书 3. **证书独立管理**: - 每个主域名独立申请证书 - 别名域名作为 SAN 添加到主域名证书中 - 证书更新后自动重载 Nginx ## 常用命令 ```bash # 启动服务 docker-compose up -d # 查看日志 docker-compose logs -f # 重启服务 docker-compose restart # 停止服务 docker-compose down # 手动检查新域名 docker-compose exec nginx-certbot /check-new-domains.sh # 手动续期证书 docker-compose exec nginx-certbot /renew-certs.sh # 查看所有证书 docker-compose exec nginx-certbot certbot certificates # 重载 Nginx 配置 docker-compose exec nginx-certbot nginx -s reload # 测试 Nginx 配置 docker-compose exec nginx-certbot nginx -t # 查看证书日志 docker-compose exec nginx-certbot cat /var/log/letsencrypt/letsencrypt.log ``` ## 使用场景 ### 场景 1:多个独立网站 ```bash # 网站 1 domains/site1.com.conf: PRIMARY_DOMAIN="site1.com" ALIAS_DOMAINS="www.site1.com" ROOT_DIR="/usr/share/nginx/html/site1" # 网站 2 domains/site2.com.conf: PRIMARY_DOMAIN="site2.com" ALIAS_DOMAINS="www.site2.com" ROOT_DIR="/usr/share/nginx/html/site2" ``` ### 场景 2:主站 + API ```bash # 主站 domains/example.com.conf: PRIMARY_DOMAIN="example.com" ALIAS_DOMAINS="www.example.com" ROOT_DIR="/usr/share/nginx/html" # API domains/api.example.com.conf: PRIMARY_DOMAIN="api.example.com" BACKEND_URL="http://api-backend:3000" ``` ### 场景 3:动态添加新域名 ```bash # 1. 添加新域名配置 ./add-domain.sh new-site.com www.new-site.com # 2. 重启容器 docker-compose restart # 3. 等待自动申请证书(或手动触发) docker-compose exec nginx-certbot /check-new-domains.sh ``` ## 配置说明 ### 证书检查周期 通过 `CERT_CHECK_INTERVAL` 环境变量配置(单位:小时): - 默认值:12 小时 - 推荐值:12-24 小时 - Let's Encrypt 证书有效期 90 天,会在到期前 30 天自动续期 ### 新域名检查 - 每小时自动检查 `domains/` 目录 - 发现新域名配置后自动申请证书 - 申请成功后自动生成 Nginx 配置并重载 ### 测试环境 首次部署建议使用测试环境(`STAGING=1`),避免触发 Let's Encrypt 速率限制: - 生产环境限制:每周每域名 50 个证书 - 测试环境无限制,但证书不被浏览器信任 ## 注意事项 1. **DNS 配置**:确保所有域名已正确解析到服务器 IP 2. **防火墙**:确保 80 和 443 端口开放 3. **域名配置**:每个域名一个配置文件,文件名建议与主域名一致 4. **证书独立**:每个主域名独立证书,别名域名共享主域名证书 5. **数据持久化**:`certbot/conf` 目录包含所有证书,请妥善备份 6. **自定义配置**:在 `sites-enabled` 文件的 `CUSTOM` 区域内添加自定义指令,重启或重新生成配置时会自动保留 ## 故障排查 ### 证书申请失败 ```bash # 查看详细日志 docker-compose logs nginx-certbot docker-compose exec nginx-certbot cat /var/log/letsencrypt/letsencrypt.log # 检查域名解析 nslookup your-domain.com # 测试 HTTP 访问 curl http://your-domain.com/.well-known/acme-challenge/test # 手动申请证书(调试) docker-compose exec nginx-certbot certbot certonly --webroot -w /var/www/certbot -d your-domain.com --dry-run ``` ### Nginx 配置错误 ```bash # 测试配置 docker-compose exec nginx-certbot nginx -t # 查看错误日志 docker-compose exec nginx-certbot cat /var/log/nginx/error.log # 查看生成的配置 docker-compose exec nginx-certbot cat /etc/nginx/sites-enabled/your-domain.com.conf ``` ### 新域名未自动申请证书 ```bash # 检查域名配置是否正确 cat domains/your-domain.com.conf # 手动触发新域名检查 docker-compose exec nginx-certbot /check-new-domains.sh # 查看新域名检查日志 docker-compose exec nginx-certbot cat /var/log/letsencrypt/new-domains.log ``` ## 高级配置 ### 自定义 Nginx 配置 每个 `nginx/sites-enabled/` 下的配置文件分为两个区域: ```nginx # --- MANAGED:BEGIN --- # 由脚本自动生成,每次重新生成时覆盖 # 包含:server 块、SSL 配置、proxy_pass / root 等 # --- MANAGED:END --- # --- CUSTOM:BEGIN --- # 用户自定义区域,重新生成时完整保留 # 在此添加自定义指令,例如: gzip on; gzip_types text/plain text/css application/json; client_max_body_size 100m; add_header X-Frame-Options DENY always; # --- CUSTOM:END --- ``` **使用规则:** - 只在 `CUSTOM` 区域内添加自定义配置,`MANAGED` 区域不要手动修改 - 容器重启、证书申请成功、手动执行 `generate-nginx-config.sh` 时,`MANAGED` 区域会更新,`CUSTOM` 区域保持不变 - 首次生成时会自动创建空的 `CUSTOM` 区域作为占位 **常见自定义示例:** ```nginx # --- CUSTOM:BEGIN --- # 大文件上传(如 4GB) client_max_body_size 4096m; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_request_buffering off; # Gzip 压缩 gzip on; gzip_types text/plain text/css application/json application/javascript; # 安全 Header add_header X-Frame-Options DENY always; add_header X-Content-Type-Options nosniff always; # 额外 location location /metrics { deny all; return 403; } # --- CUSTOM:END --- ``` ### 运行配置生成测试 ```bash bash scripts/test-generate-nginx-config.sh ``` 覆盖 10 个场景:首次生成、gzip、rate limit、自定义 header、额外 location、SSL 状态切换、BACKEND_URL 变更、别名域名变更、旧格式文件迁移。 ## 许可证 本项目基于 MIT 许可证开源。