如何在Docker环境中配置SSL/Let's Encrypt实现HTTPS加密
为Docker化的Express/Handlebars网站配置Let's Encrypt SSL的可行方案
以下是几种实用的方案,适合Docker新手快速实现HTTPS访问:
方案一:Nginx反向代理 + Certbot(最通用)
这是成熟度最高的方案,通过Nginx处理SSL终止,Certbot自动完成证书的申请与更新。
步骤:
- 编写Nginx配置文件
创建nginx/default.conf,配置反向代理指向你的Express容器,同时预留SSL相关配置:
server { listen 80; server_name your-domain.com; # 处理Certbot的ACME域名验证请求 location /.well-known/acme-challenge/ { root /var/www/certbot; } # 强制将所有HTTP请求重定向到HTTPS location / { return 301 https://$host$request_uri; } } 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; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # 反向代理到Express容器(假设容器内部端口为3000) location / { proxy_pass http://express-app:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
- 编写Docker Compose编排文件
创建docker-compose.yml,整合Express、Nginx和Certbot服务:
version: '3.8' services: express-app: build: ./your-express-project-dir # 替换为你的Express项目目录路径 ports: - "3000:3000" # 可添加环境变量、数据卷等其他配置 nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf - certbot-etc:/etc/letsencrypt - certbot-var:/var/www/certbot depends_on: - express-app certbot: image: certbot/certbot volumes: - certbot-etc:/etc/letsencrypt - certbot-var:/var/www/certbot command: certonly --webroot -w /var/www/certbot --email your-email@example.com --agree-tos --no-eff-email -d your-domain.com
- 启动服务并完成证书配置
- 执行
docker-compose up -d启动所有服务 - 首次运行后,Certbot会自动申请证书,执行
docker-compose restart nginx让Nginx加载SSL配置 - 配置证书自动更新:添加系统定时任务(如cron),定期执行
docker-compose run --rm certbot renew,完成后重启Nginx
方案二:直接在Express应用中集成Let's Encrypt
适合不想额外部署反向代理的简单场景,通过Node.js库自动管理证书生命周期。
步骤:
- 安装依赖库
在Express项目目录下执行:
npm install greenlock-express
- 修改Express入口文件
用greenlock包裹原有Express应用,实现自动SSL:
const express = require('express'); const greenlock = require('greenlock-express'); const app = express(); // 保留你的原有配置(Handlebars模板、路由、中间件等) app.set('view engine', 'hbs'); // ...其他业务路由配置 // 启动带SSL自动管理的服务 greenlock.init({ packageRoot: __dirname, configDir: './greenlock.d', maintainerEmail: 'your-email@example.com', cluster: false }) .serve(app);
- 配置Docker容器
确保Dockerfile暴露80和443端口:
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 80 443 CMD ["node", "server.js"]
启动容器时映射端口:
docker run -p 80:80 -p 443:443 your-express-image-name
注意:该方案需要容器直接暴露80/443端口,且80端口需对外可达以完成ACME验证,仅适合单容器简单场景。
方案三:使用Traefik作为自动反向代理
Traefik是云原生反向代理工具,自带Let's Encrypt自动证书管理,适合多容器微服务环境。
步骤:
- 编写Traefik配置文件
创建traefik.yml:
api: dashboard: true entryPoints: web: address: ":80" websecure: address: ":443" certificatesResolvers: letsencrypt: acme: email: your-email@example.com storage: acme.json httpChallenge: entryPoint: web providers: docker: exposedByDefault: false
- 编写Docker Compose文件
version: '3.8' services: traefik: image: traefik:v2.9 command: --api.insecure=true --providers.docker ports: - "80:80" - "443:443" - "8080:8080" # Traefik仪表盘端口 volumes: - /var/run/docker.sock:/var/run/docker.sock - ./traefik.yml:/etc/traefik/traefik.yml - ./acme.json:/acme.json express-app: build: ./your-express-project-dir labels: - "traefik.enable=true" - "traefik.http.routers.express.rule=Host(`your-domain.com`)" - "traefik.http.routers.express.entrypoints=websecure" - "traefik.http.routers.express.tls.certresolver=letsencrypt" - "traefik.http.services.express.loadbalancer.server.port=3000"
- 启动服务
执行docker-compose up -d,Traefik会自动检测Express容器,完成证书申请、SSL配置,同时自动处理HTTP到HTTPS的重定向。
内容的提问来源于stack exchange,提问作者Diego Alves
相关产品推荐
相关产品推荐

