如何在CI/CD工作流中为本地测试及生产环境配置Let's Encrypt HTTPS?
我来给你梳理下这个问题的解决方案,其实完全不用额外购买证书,我们可以分开处理本地测试和生产环境的HTTPS需求,再顺畅整合到CI/CD工作流里:
一、本地测试HTTPS的两种可行方案
因为本地环境没法满足Let's Encrypt的DNS验证要求,所以我们用本地专用证书就能搞定Vue PWA的Service Worker测试需求:
1. 快速生成自签名证书(零额外工具)
用OpenSSL就能直接生成,执行这条命令就行:
openssl req -x509 -newkey rsa:4096 -nodes -keyout localhost.key -out localhost.crt -days 365 -subj "/CN=localhost"
这条命令会生成有效期1年的localhost.key(私钥)和localhost.crt(证书)。接下来在你的生产版Docker Compose配置里,把这两个文件挂载到Nginx容器的对应目录(比如/etc/nginx/ssl/),然后修改Nginx的配置文件,开启SSL:
server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/localhost.crt; ssl_certificate_key /etc/nginx/ssl/localhost.key; # 其他反向代理配置... }
启动容器后,浏览器会提示“不安全”,手动信任这个证书就行——毕竟是本地测试,完全不影响Service Worker的正常注册。记得把这两个证书文件加到.gitignore里,别提交到代码仓库。
2. 用mkcert生成系统信任的证书(更友好)
如果不想每次都点信任,推荐用mkcert这个小工具,它会给你的本地系统安装一个自定义根证书,生成的localhost证书会被浏览器自动信任:
- 先安装mkcert:比如Mac用
brew install mkcert,Linux用对应包管理器,Windows用Chocolatey或者直接下载二进制文件 - 初始化本地CA:
mkcert -install - 生成多域名证书(覆盖localhost、127.0.0.1等):
mkcert localhost 127.0.0.1 ::1 - 之后的Docker挂载和Nginx配置和上面一样,只是证书文件名变成
localhost+2.pem和localhost+2-key.pem(具体看生成的文件)。这样打开本地HTTPS地址时,浏览器会显示安全锁,体验和生产环境一致。
二、生产环境用Let's Encrypt的标准流程
生产环境还是老老实实用Certbot,毕竟免费、自动续期,完全满足需求:
1. 用Docker化的Certbot配合Nginx
在你的生产版Docker Compose里添加Certbot服务:
services: nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx/prod.conf:/etc/nginx/conf.d/default.conf - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/html certbot: image: certbot/certbot volumes: - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/html
第一次部署时,先启动Nginx:docker-compose up -d nginx,然后运行Certbot获取证书:
docker-compose run --rm certbot certonly --webroot -w /var/www/html --email your-email@example.com --agree-tos --no-eff-email -d your-domain.com
替换your-email@example.com和your-domain.com为你的真实邮箱和域名。获取成功后,修改Nginx配置指向Let's Encrypt的证书:
server { listen 443 ssl; server_name your-domain.com; ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; # 其他反向代理配置... } # 还要加个80端口的重定向到443 server { listen 80; server_name your-domain.com; return 301 https://$host$request_uri; }
重启Nginx即可生效。
2. 配置自动续期
Let's Encrypt证书有效期90天,所以必须配置自动续期。可以在服务器上添加一个Cron任务:
# 每天中午12点检查续期,续期成功就重启Nginx 0 12 * * * /usr/bin/docker-compose -f /path/to/your/docker-compose.yml run --rm certbot renew && /usr/bin/docker-compose -f /path/to/your/docker-compose.yml restart nginx
也可以用Docker的定时服务来实现,不过Cron更简单直接。
三、整合到CI/CD工作流
把上面的步骤整合到你的CI/CD pipeline里,就能实现本地测试和生产部署的无缝衔接:
1. 本地测试阶段
- 在CI/CD的预提交检查或本地测试脚本里,加入生成证书的步骤(比如用OpenSSL快速生成),确保启动的生产镜像默认用HTTPS
- 把证书生成命令写到项目的
Makefile或者package.json的脚本里,比如npm run cert:local,方便开发人员一键生成 - 确保证书文件在
.gitignore里,避免污染代码仓库
2. 生产部署阶段
- 在CI/CD脚本里,先检查服务器上是否已经存在Let's Encrypt证书:如果是首次部署,就执行Certbot获取证书的命令;如果已经有证书,直接启动服务即可
- 部署完成后,自动触发一次证书续期检查,确保证书有效
- 把Cron任务的配置也加到CI/CD的部署脚本里,确保新服务器也会自动续期证书
总结:不需要购买第三方证书
完全没必要花钱买其他CA的证书,本地用自签名或mkcert就能满足测试需求,生产用Let's Encrypt的自动流程即可,全程不需要手动更新证书,CI/CD整合起来也很顺畅。
备注:内容来源于stack exchange,提问作者luke

