所有部署指南 部署

Docker 与反向代理的 SSL 证书配置

Docker 容器通常不直接处理 SSL——前面的反向代理负责终结 TLS 并将解密后的流量转发给容器。本指南涵盖三种最常见的方案。

方案一:Nginx 反向代理 + 手动证书

最适合小型部署的简单方案。从 GetHTTPS 获取证书并挂载到 Nginx 容器中。

docker-compose.yml

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs/fullchain.pem:/etc/ssl/fullchain.pem:ro
      - ./certs/privkey.pem:/etc/ssl/privkey.pem:ro
    depends_on:
      - app

  app:
    image: your-app:latest
    expose:
      - "3000"

nginx.conf

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate     /etc/ssl/fullchain.pem;
    ssl_certificate_key /etc/ssl/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://app:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;
}

续签方式: 用来自 GetHTTPS 的新文件替换 ./certs/ 中的文件,然后执行 docker compose exec nginx nginx -s reload

方案二:Traefik 自动获取 Let’s Encrypt

Traefik 是为容器构建的反向代理,可以自动获取和续签 Let’s Encrypt 证书。

docker-compose.yml

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/acme/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik-acme:/acme

  app:
    image: your-app:latest
    labels:
      - "traefik.http.routers.app.rule=Host(`yourdomain.com`)"
      - "traefik.http.routers.app.tls.certresolver=letsencrypt"
      - "traefik.http.services.app.loadbalancer.server.port=3000"

volumes:
  traefik-acme:

Traefik 处理一切:证书签发、续签和 HTTPS 终结。无需手动管理证书。

方案三:Caddy(零配置 HTTPS)

Caddy 自动获取和续签 Let’s Encrypt 证书,完全零配置。

docker-compose.yml

services:
  caddy:
    image: caddy:2
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
    depends_on:
      - app

  app:
    image: your-app:latest
    expose:
      - "3000"

volumes:
  caddy-data:

Caddyfile

yourdomain.com {
    reverse_proxy app:3000
}

这就是全部配置。Caddy 会获取 Let’s Encrypt 证书并自动续签。

如何选择?

Nginx + 手动证书TraefikCaddy
配置难度中等(配置 + 证书文件)中等(标签配置)极简
自动续签❌(手动)
灵活性中等
学习曲线低(熟悉)中等
最适合小型部署,完全控制动态容器,微服务简单站点,最少配置

Docker 中的证书续签

方案一(Nginx + 手动):

# Replace cert files in your local ./certs/ directory
cp new-fullchain.pem ./certs/fullchain.pem
cp new-privkey.pem ./certs/privkey.pem

# Reload Nginx inside the container (no restart needed)
docker compose exec nginx nginx -s reload

方案二(Traefik)和方案三(Caddy):

自动处理——它们在内部管理续签。证书存储在 Docker 卷(traefik-acmecaddy-data)中,在容器重启后仍然保留。

Docker Swarm:使用 secrets

对于 Docker Swarm 部署,使用 Docker secrets 代替绑定挂载证书文件:

# Create secrets from your cert files
docker secret create ssl_cert fullchain.pem
docker secret create ssl_key privkey.pem
# In docker-compose.yml (deploy mode)
services:
  nginx:
    image: nginx:alpine
    secrets:
      - ssl_cert
      - ssl_key
    configs:
      - source: nginx_conf
        target: /etc/nginx/conf.d/default.conf

secrets:
  ssl_cert:
    external: true
  ssl_key:
    external: true

Secrets 在容器内挂载到 /run/secrets/ssl_cert/run/secrets/ssl_key——静态和传输中都加密。

常见错误

将证书打包进 Docker 镜像

# ❌ NEVER do this
COPY fullchain.pem /etc/ssl/fullchain.pem
COPY privkey.pem /etc/ssl/privkey.pem

证书每 90 天过期一次。打包进镜像意味着每 60 天就要重新构建和重新部署。始终以卷或 secrets 方式挂载证书。

忘记暴露端口 80

端口 80 用于:

  • HTTP → HTTPS 重定向
  • Let’s Encrypt HTTP-01 验证(Traefik/Caddy 自动续签需要)
ports:
  - "80:80"    # Don't forget this
  - "443:443"

未持久化 ACME 数据

Traefik 和 Caddy 将 Let’s Encrypt 证书和账户密钥存储在卷中。没有持久化,它们会在每次容器重启时重新请求证书——并触发速率限制:

volumes:
  traefik-acme:    # MUST be a named volume, not anonymous
  caddy-data:

常见问题

应用容器可以直接处理 SSL 吗?

可以,但不推荐。反向代理模式(在边缘终结 TLS,内部转发明文 HTTP)是标准做法,因为:应用不需要知道证书的事情,续签不需要重启应用,而且你可以集中管理 TLS 配置。

如何为多个容器配置 SSL?

使用 Traefik 或 Caddy 时,为每个服务添加标签/配置——它们会自动获取各自的证书。使用 Nginx 时,在配置中添加多个 server 块。

应该用 GetHTTPS 还是 Traefik 内置的 ACME?

生产环境推荐使用 Traefik/Caddy 内置的 ACME——它自动处理续签。当你需要为 Nginx 反向代理方案(方案一)获取证书,或容器没有直接互联网访问无法完成 ACME 验证时,使用 GetHTTPS

如何在 Docker 中安全地挂载证书?

以只读模式挂载(:ro),在 Swarm 模式下对私钥使用 Docker secrets,确保只有反向代理容器能访问证书文件。永远不要将证书打包进 Docker 镜像——它们会过期,你需要重新构建。

可以在 Kubernetes 中使用 GetHTTPS 证书吗?

可以。从 GetHTTPS 证书文件创建 Kubernetes TLS secret:

kubectl create secret tls my-tls-cert --cert=fullchain.pem --key=privkey.pem

然后在 Ingress 资源中引用它。要在 Kubernetes 中实现自动续签,可以考虑使用 cert-manager 配合 Let’s Encrypt ClusterIssuer。

相关文章

部署 2026-05-08
如何在 Nginx 上安装 SSL 证书
在 Nginx 上安装 SSL 证书的分步指南。涵盖文件上传、完整 server 块配置、TLS 最佳实践、HTTP/2、HSTS、重定向设置、测试以及 6 个常见错误的排查方法。
快速开始 2026-05-08
如何获取免费 SSL 证书(分步指南)
5 分钟从 Let's Encrypt 获取免费 SSL 证书 — 无需安装软件、无需注册账号。涵盖 4 种方法、两种验证方式、6 个平台的安装教程和故障排除。
对比 2026-05-07
浏览器 ACME 客户端 vs 命令行 ACME 客户端
对比浏览器端 ACME 客户端(如 GetHTTPS)与命令行工具(Certbot、acme.sh)。了解在隐私、自动化和应用场景方面的权衡。
在浏览器中获取免费 SSL 证书
无需安装,无需账号。私钥始终留在你的设备上。
获取证书