Nginx 示例
- 代理 - server {
    listen 80;
    listen [::]:80;
    server_name xxx.bqbp.cn;
    charset utf-8;
    index index.html;
    root /data/wwwroot/proxy;
    set $to_https 0;
    if ($scheme = "http") {
        set $to_https 1;
    }
    include wildcard/bqbp.cn.conf;
    access_log /data/wwwlogs/xxx.bqbp.cn.log;
    error_log /data/wwwlogs/xxx.bqbp.cn_error.log;
    #禁止访问的文件或目录
    location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
    {
        return 404;
    }
    # 一键申请SSL证书验证目录相关设置
    location ~ \.well-known{
        allow all;
    }
    # 禁止显示索引文件列表
    location ~* ^/([a-z-]+)/?$ {
        return 301 https://forum.idev.top;
    }     
    # To allow special characters in headers
    ignore_invalid_headers off;
    # Allow any size file to be uploaded.
    # Set to a value such as 1000m; to restrict file size to a specific value
    client_max_body_size 0;
    # To disable buffering
    proxy_buffering off;
    proxy_request_buffering off;
    location / {
        proxy_set_header Host $http_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;
        proxy_set_header X-NginX-Proxy true;
        real_ip_header X-Real-IP;
        proxy_connect_timeout 300;
        # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        chunked_transfer_encoding off;
        proxy_pass http://127.0.0.1:39007; 
    }
}
 
- 代理 + Websocket - server {
    listen 80;
    listen [::]:80; 
    server_name xxx.bqbp.cn;
    set $to_https 0;
    if ($scheme = "http") {
        set $to_https 1;
    }
    include wildcard/bqbp.cn.conf;
    index  index.html index.htm;
    root   /data/wwwroot/proxy;
    
    access_log /data/wwwlogs/xxx.bqbp.cn.log;
    error_log /data/wwwlogs/xxx.bqbp.cn_error.log;
    
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    # proxy
    location / {
        proxy_pass   http://127.0.0.1:39009;
        client_max_body_size  1024m;
        # 关键协议头设置
        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;  # 透传 HTTPS 协议标识
        proxy_set_header X-Forwarded-Ssl on;         # 明确 SSL 启用状态
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout 99999;
    }
    # websocket
    location = /ws {
        if ($http_upgrade != "websocket") { # WebSocket协商失败时返回404
            return 500;
        }
        # ngnix doc
        ## https://nginx.org/en/docs/http/websocket.html
        ## https://www.nginx.com/blog/websocket-nginx/
        proxy_pass http://127.0.0.1:31988;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        # proxy_set_header Connection $connection_upgrade; # 升级 http1.1 到 websocket 协议
        proxy_set_header Host $host;
        proxy_set_header Connection "Upgrade";
        proxy_redirect off;
        # Show real IP in access.log
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }
    location /.well-known/ {
        allow all;
    }
}
 
强制容器内部 HTTPS(高级场景)
1. 生成自签名证书
# 在 Docker 宿主机生成证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ./self-signed.key -out ./self-signed.crt
2. Docker 容器 HTTPS 配置   
挂载证书并配置应用启用 HTTPS:
# docker-compose.yml 示例
version: '3'
services:
  your-app:
    image: your-image
    ports:
      - "1234:443"  # 暴露 HTTPS 端口
    volumes:
      - ./self-signed.crt:/app/certs/cert.crt
      - ./self-signed.key:/app/certs/cert.key
    command: [
      "--ssl-cert=/app/certs/cert.crt",
      "--ssl-key=/app/certs/cert.key"
    ]
3. Nginx 反向代理调整
location / {
    proxy_pass https://127.0.0.1:1234;  # 注意改为 https 协议
    proxy_ssl_verify off;               # 跳过证书验证(自签名时需加)
    # 保持协议头透传配置
}
以下是分步骤的解决方案:
场景分析
当使用 Nginx 反向代理 Docker 容器服务时,若要让容器内部应用认为外部请求使用的是 HTTPS 协议,需要通过 协议头转发 实现。以下是具体配置步骤:
方案一:Nginx 协议头透传(推荐)
1. Nginx 配置修改
server {
    listen 443 ssl;
    server_name your-domain.com;
    # SSL 证书配置
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    location / {
        proxy_pass http://127.0.0.1:1234;  # 指向 Docker 容器端口
        # 关键协议头设置
        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;  # 透传 HTTPS 协议标识
        proxy_set_header X-Forwarded-Ssl on;         # 明确 SSL 启用状态
    }
}
2. Docker 应用适配
确保容器内的应用能正确读取 X-Forwarded-Proto 头部,常见框架配置示例:
- Node.js (Express) -   app.set('trust proxy', true); // 信任代理头
  app.use((req, res, next) => {
    if (req.protocol === 'https') {
      // 处理 HTTPS 逻辑
    }
    next();
  });
 
- Python (Flask) -   from werkzeug.middleware.proxy_fix import ProxyFix
  app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1)
 
- Spring Boot (Java) -   server.tomcat.remoteip.remote-ip-header=x-forwarded-for
  server.tomcat.protocol-header=x-forwarded-proto
 
方案二:强制容器内部 HTTPS(高级场景)
1. 生成自签名证书
# 在 Docker 宿主机生成证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ./self-signed.key -out ./self-signed.crt
2. Docker 容器 HTTPS 配置
挂载证书并配置应用启用 HTTPS:
# docker-compose.yml 示例
version: '3'
services:
  your-app:
    image: your-image
    ports:
      - "1234:443"  # 暴露 HTTPS 端口
    volumes:
      - ./self-signed.crt:/app/certs/cert.crt
      - ./self-signed.key:/app/certs/cert.key
    command: [
      "--ssl-cert=/app/certs/cert.crt",
      "--ssl-key=/app/certs/cert.key"
    ]
3. Nginx 反向代理调整
location / {
    proxy_pass https://127.0.0.1:1234;  # 注意改为 https 协议
    proxy_ssl_verify off;               # 跳过证书验证(自签名时需加)
    # 保持协议头透传配置
}
常见问题排查
- 应用不识别协议头 
- 证书错误 
- Docker 网络不通