悠悠楠杉
在Docker中配置HTTPS证书的完整指南
为什么需要 HTTPS?
当你在 Docker 中部署 Web 服务时,HTTPS 不再是可选项而是必选项。现代浏览器会对非 HTTPS 网站标记"不安全",而 API 服务没有 HTTPS 更会导致连接被拒绝。去年我们团队就曾因为测试环境未配置 HTTPS,导致移动端应用无法正常调用接口。
准备工作
在开始之前你需要:
1. 已安装 Docker 和 docker-compose
2. 拥有域名(如需使用 Let's Encrypt)
3. 服务器 80/443 端口开放
实测环境:Ubuntu 20.04 LTS / Docker 20.10.12
方案一:自签名证书(适合测试环境)
1. 生成证书
bash
mkdir -p ~/certs && cd ~/certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key -out server.crt \
-subj "/CN=yourdomain.com"
2. Docker 容器配置
以 Nginx 容器为例:dockerfile
Dockerfile
FROM nginx:alpine
COPY server.crt /etc/nginx/certs/
COPY server.key /etc/nginx/certs/
COPY nginx.conf /etc/nginx/conf.d/
配套的 nginx.conf 配置:
nginx
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
# 其他配置...
}
3. 运行容器
bash
docker build -t https-app .
docker run -p 443:443 https-app
注意:自签名证书会触发浏览器警告,需要手动添加信任
方案二:Let's Encrypt(生产环境推荐)
1. 使用 certbot 自动获取证书
bash
docker run -it --rm \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
-p 80:80 \
certbot/certbot certonly \
--standalone -d yourdomain.com --agree-tos
2. 配置自动续期
创建 renew.sh 脚本:bash
!/bin/bash
docker run --rm \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
certbot/certbot renew
添加到 crontab:
0 3 * * * /path/to/renew.sh >> /var/log/certbot.log
3. Nginx 集成方案
推荐使用 docker-compose 编排:yaml
version: '3'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- /etc/letsencrypt:/etc/letsencrypt
depends_on:
- app
app:
image: your-application
对应的 Nginx 配置关键部分:nginx
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
proxy_pass http://app:3000;
}
}
常见问题排查
证书不生效:
- 检查证书路径映射是否正确
- 使用
docker exec -it nginx sh
进入容器验证文件是否存在
SSL 协议错误:
nginx ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;
混合内容警告:
确保所有静态资源也使用 HTTPS 加载
进阶技巧
- 使用 DNS 验证:适合没有 80 端口的场景
- OCSP Stapling:提升 SSL 握手性能
nginx ssl_stapling on; ssl_stapling_verify on;
安全建议
- 定期轮换证书(Let's Encrypt 证书有效期 90 天)
- 禁用旧版 TLS 协议
- 使用 Docker secrets 管理密钥(Swarm 模式下)
bash echo "your_private_key" | docker secret create ssl_key -
结语
HTTPS 配置看似复杂,但通过 Docker 的标准化部署可以大大简化流程。笔者建议生产环境直接采用 Let's Encrypt 方案,既免费又安全。去年我们通过自动化部署,将证书管理时间从每月 4 小时降低到 15 分钟。