使用 docker-compose 启动的 nginx 容器证书过期

使用 docker-compose 启动的 nginx 容器证书过期

解决方案:重新申请并部署新的 SSL 证书

我的方案:使用 Let's Encrypt + Certbot(更自动化)

1:运行 certbot 生成证书

假设域名为:mydomain.com,登录服务器用户 u1,nginx容器名:nginx-web

有公网 IP 和域名解析。

由于我80端口已经被nginx占用,使用 --webroot 插件(最推荐!无需停 Nginx)

如果你的 Nginx 已经在提供网站服务,可以利用现有 Web 目录完成验证。

1.1:确保 Nginx 能正确响应 /.well-known/acme-challenge/ 路径在你的 Nginx 配置中添加(或确认已有):

nginx 复制代码
server {
    listen 80;
    server_name mydomain.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;  # 或你指定的 webroot 路径
    }

    location / {
        # 你的正常网站配置
    }
}

1.2:在宿主机创建 challenge 目录并挂载到容器

bash 复制代码
sudo mkdir -p /var/www/certbot

1.3:如果你用 docker-compose.yml,确保 Nginx 容器挂载了这个目录:

yaml 复制代码
volumes:
  - /var/www/certbot:/var/www/certbot:ro

修改了配置,需要重启容器

bash 复制代码
docker-compose up -d --force-recreate nginx-web

1.4:运行 certbot 使用 --webroot

bash 复制代码
sudo certbot certonly \
  --webroot \
  -w /var/www/certbot \
  -d mydomain.com

✅ 这样 Certbot 会把验证文件写入 /var/www/certbot/.well-known/acme-challenge/,Nginx 会正常响应,无需停服务!

证书路径通常为:

  • /etc/letsencrypt/live/mydomain.com/fullchain.pem
  • /etc/letsencrypt/live/mydomain.com/privkey.pem

然后挂载到 Docker 即可。

💡 Let's Encrypt 证书有效期 90 天,但可以自动续期(配合 cron 或 watchtower)。

1.5 验证新证书是否生效

部署后再次测试:

bash 复制代码
curl -v https://mydomain.com --resolve mydomain.com:443:127.0.0.1

也可检查证书日期:

bash 复制代码
openssl x509 -in /home/u1/docker/nginx/certs/fullchain.pem -noout -dates

输出应类似:

bash 复制代码
notBefore=Nov 20 00:00:00 2025 GMT
notAfter=Feb 18 23:59:59 2026 GMT

临时绕过(仅调试用)

如果你只是想临时测试服务是否正常,可以用:

bash 复制代码
curl -k https://localhost

2:创建一个由 root 执行的复制脚本

因为我当前登录服务器的用户 u1 没有root权限。

推荐方法:让 certbot renew 通过 --deploy-hook 自动复制证书(由 root 执行)

2.1:创建一个由 root 执行的复制脚本

bash 复制代码
sudo nano /usr/local/bin/copy-ssl-to-nginx.sh

内容如下:

bash 复制代码
#!/bin/bash
# 复制证书到 u1 有权限的目录
cp -L /etc/letsencrypt/live/mydomain.com/fullchain.pem /home/u1/docker/nginx/cert/
cp -L /etc/letsencrypt/live/mydomain.com/privkey.pem /home/u1/docker/nginx/cert/

# 设置正确权限(确保 u1 可读)
chown u1:u1 /home/u1/docker/nginx/cert/{fullchain.pem,privkey.pem}
chmod 644 /home/u1/docker/nginx/cert/fullchain.pem
chmod 600 /home/u1/docker/nginx/cert/privkey.pem

# 重载 Nginx(使用 docker-compose, nginx-web是容器名)
# /usr/local/bin/docker-compose 是 docker-compose 的绝对路径
cd /home/u1/docker/compose-yml || exit 1
sudo -u u1 /usr/local/bin/docker-compose exec -T nginx-web nginx -s reload

执行写入命令:Ctrl+W

执行退出命令:Ctrl+O

保存后,赋予执行权限:

bash 复制代码
sudo chmod +x /usr/local/bin/copy-ssl-to-nginx.sh

2.1.1:找到 docker-compose 的绝对路径

以你的普通用户身份运行:

bash 复制代码
which docker-compose

常见输出示例:

  • /usr/local/bin/docker-compose
  • /home/u1/.local/bin/docker-compose
  • /usr/bin/docker-compose

2.2:配置 Certbot 使用 --deploy-hook(推荐)或 --post-hook

--deploy-hook :仅在证书实际更新时才执行(比 --post-hook 更高效)

修改 Certbot 的 renewal 配置(推荐)

找到你的域名对应的 renewal 配置:

bash 复制代码
sudo nano /etc/letsencrypt/renewal/mydomain.com.conf

[renewalparams] 段落下添加:

bash 复制代码
deploy_hook = /usr/local/bin/copy-ssl-to-nginx.sh

保存退出。

📝 示例片段:

ini 复制代码
[renewalparams]
...
deploy_hook = /usr/local/bin/copy-ssl-to-nginx.sh

2.3: 最终自动化流程(无需你的用户参与复制)

  1. 系统定时任务运行:sudo certbot renew
  2. 如果证书需要更新:
    • Certbot 获取新证书(root 权限)
    • 自动触发 deploy_hook
    • root 执行脚本:复制证书 → 改权限 → 重载 Nginx(以 cm1 身份调用 docker-compose)
  3. 你的网站无缝使用新证书 ✅

3: 设置 root 的定时任务(推荐)

3.1: 设置定时任务

bash 复制代码
sudo crontab -e

添加:

bash 复制代码
0 3 * * * /usr/bin/certbot renew --quiet

3.2: ✅ 验证

手动触发一次(测试):

bash 复制代码
sudo certbot renew --force-renewal --deploy-hook "/usr/local/bin/copy-ssl-to-nginx.sh"

然后检查:

bash 复制代码
ls -l /home/u1/docker/nginx/cert/
cat /home/u1/docker/nginx/cert/fullchain.pem  # 应该能读
相关推荐
Nonoas13 小时前
动态代理:发布订阅的高级玩法
java·ide·intellij-idea
程序员-周李斌13 小时前
Java 死锁
java·开发语言·后端
皮皮林55114 小时前
Prometheus+Grafana,打造强大的监控与可视化平台
java
JasmineWr14 小时前
CompletableFuture相关问题
java·开发语言
零雲14 小时前
java面试:知道java的反射机制吗
java·开发语言·面试
java1234_小锋15 小时前
Java进程占用的内存有哪些部分?
java
sxlishaobin15 小时前
Spring Bean生命周期详解
java·后端·spring
曹牧15 小时前
Java:Assert.isTrue()
java·前端·数据库
梦里小白龙15 小时前
JAVA 策略模式+工厂模式
java·开发语言·策略模式
你不是我我16 小时前
【Java 开发日记】我们来说一说 Redis 主从复制的原理及作用
java·redis·github