Docker 部署 HTTPS 最常见的坑:证书路径写错、配置不生效、续签失败。这篇教程覆盖两种场景——开发环境用自签名证书快速验证,生产环境用 Let’s Encrypt 免费证书 + 自动续签,让你少走弯路。
确保服务器已安装:
自签名证书不受浏览器信任,适合开发调试或内网服务,3 分钟搞定。
mkdir -p /opt/nginx/ssl openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /opt/nginx/ssl/nginx.key -out /opt/nginx/ssl/nginx.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=Dev/CN=localhost"
生成两个文件:nginx.key(私钥)和 nginx.crt(证书),有效期 365 天。
创建 /opt/nginx/conf.d/ssl.conf:
server }
注意:
ssl_certificate填的是容器内路径,不是宿主机路径!这是最常见的配置错误。
docker run -d --name my-nginx -p 80:80 -p 443:443 -v /opt/nginx/conf.d:/etc/nginx/conf.d -v /opt/nginx/ssl:/etc/nginx/ssl nginx
访问 https://localhost 验证,浏览器会提示”不安全”(自签名正常现象),点击继续即可。
docker exec my-nginx nginx -s reload
Let’s Encrypt 证书当前有效期 90 天(2027 年起将逐步缩短至 45 天),Certbot 按约 2/3 有效期自动续签。整套方案用两个容器搞定:Nginx 负责反向代理,Certbot 负责证书申请和续签。
/opt/myapp/
├── docker-compose.yml
├── nginx/
│ ├── conf.d/
│ │ └── app.conf
│ └── html/
├── certbot/
│ ├── conf/ # 证书存储目录
│ └── www/ # HTTP 验证临时目录
version: '3'
services:
nginx:
image: nginx:latest
container_name: my-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/html:/usr/share/nginx/html
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'"
networks:
- web
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
networks:
- web
networks:
web:
driver: bridge
两个关键设计:
创建 nginx/conf.d/app.conf(暂时只配 HTTP,不配 HTTPS):
server { listen 80; server_name your-domain.com; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } }
把 your-domain.com 替换成你的域名。
cd /opt/myapp docker-compose up -d
docker-compose run --rm certbot certonly --webroot -w /var/www/certbot -d your-domain.com --email --agree-tos --no-eff-email
看到 “Congratulations!” 提示表示申请成功,证书存放在 ./certbot/conf/live/your-domain.com/。
修改 nginx/conf.d/app.conf:
server { listen 80; server_name your-domain.com; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } server }
docker-compose exec nginx nginx -s reload
访问 https://your-domain.com 验证,地址栏出现绿锁即配置成功。
# 模拟续签(不实际执行,只验证流程) docker-compose run --rm certbot renew --dry-run # 查看续签日志 docker-compose logs certbot
配置 OCSP Stapling 和安全响应头,可以把 SSL Labs 评分提到 A+:
# 在 443 server 块内追加以下内容 # OCSP Stapling(加快证书验证速度) ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/your-domain.com/chain.pem; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # 安全响应头 add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block";
配置完成后,访问 SSL Labs 测试工具 测一下分数。
如果 Nginx 需要把流量转发给其他 Docker 容器(比如 Node.js、Go 应用),在 server 块内把 location / 替换成:
upstream backend { server backend-api:3000; # backend-api 是目标容器名 keepalive 32; } location /
容器间通信用容器名(如
backend-api:3000),不是localhost,这是 Docker 网络的基本规则。
/etc/letsencrypt/...) 申请证书失败 域名未解析到当前服务器,或 80 端口被占用 检查 DNS 解析 +
docker ps 确认 80 端口 续签后证书未生效 Nginx 未重载 Nginx 容器命令已内置每 6 小时 reload,或手动执行
nginx -s reload 502 Bad Gateway 后端容器未启动,或未加入同一网络
docker ps 检查状态,确认两个容器在同一
network 浏览器仍显示不安全 使用了自签名证书,或证书域名与访问域名不匹配 生产环境使用 Let’s Encrypt,或检查
server_name
# 检查 Nginx 配置语法 docker exec my-nginx nginx -t # 优雅重载(不中断现有连接) docker exec my-nginx nginx -s reload # 查看 Certbot 日志 docker-compose logs certbot # 测试证书续签流程 docker-compose run --rm certbot renew --dry-run
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/271391.html