You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Docker/Docker Compose配置Nginx反向代理本地端口遇连接超时

问题解决:Docker Nginx反向代理HTTPS请求超时

核心问题分析

  1. 容器内localhost指向错误:Docker容器里的localhost是容器自身的回环地址,不是宿主机。你配置里的proxy_pass http://localhost:3000/和upstream中的server localhost:3000,根本访问不到宿主机上运行的服务。
  2. Stream模块配置冲突:你在stream块里同时加了ssl_preread on和SSL证书配置,这俩是互斥的——ssl_preread是用来做不终止SSL的TCP转发,而配置SSL证书是要终止SSL加密,这种矛盾配置直接导致Nginx无法正常处理HTTPS请求。

解决方案

步骤1:修复容器访问宿主机的地址

把配置里所有指向localhost的地址,替换成宿主机的可访问地址:

  • 跨平台通用方案:用Docker内置的特殊DNS名称host.docker.internal(Docker 18.03及以上支持),它会自动解析到宿主机IP。
  • Linux替代方案:如果host.docker.internal无效,要么手动写宿主机的内网IP(比如192.168.1.100),要么在Docker Compose里加extra_hosts: - "host.docker.internal:host-gateway"(Docker 20.10及以上支持)。

步骤2:重构Nginx配置,移除错误的Stream模块

你的后端是HTTP服务,正确做法是在http模块里配置HTTPS服务器,先终止SSL再反向代理到后端,完全不需要用stream模块做TCP转发。修改后的nginx.conf如下:

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # 可选:把HTTP请求重定向到HTTPS
    server {
        listen 80;
        server_name yyy.domain2.com xxx.domain1.com;
        return 301 https://$host$request_uri;
    }

    # yyy.domain2.com的HTTPS配置
    server {
        listen 443 ssl;
        server_name yyy.domain2.com;

        chunked_transfer_encoding on;

        # SSL证书路径(注意容器内的路径)
        ssl_certificate        /etc/nginx/.cert/cert.pem;
        ssl_certificate_key    /etc/nginx/.cert/key.pem;

        # 优化SSL协议和加密套件
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";

        location / {
            proxy_pass http://host.docker.internal:3001/;
            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;
        }
    }

    # xxx.domain1.com的HTTPS配置
    server {
        listen 443 ssl;
        server_name xxx.domain1.com;

        chunked_transfer_encoding on;

        ssl_certificate        /etc/nginx/.cert/cert.pem;
        ssl_certificate_key    /etc/nginx/.cert/key.pem;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";

        location / {
            proxy_pass http://host.docker.internal: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;
        }
    }
}

# 删掉原来的stream块,不需要TCP层的SNI转发

步骤3:(可选)调整Docker Compose配置(针对Linux用户)

如果Linux系统下host.docker.internal不生效,就在docker-compose.yml里加extra_hosts配置:

version: '3.7'

services:
    proxy:
        image: nginx:alpine
        container_name: proxy
        ports:
            - '443:443'
            - '80:80'
        volumes:
            - ./nginx.conf:/etc/nginx/nginx.conf
            - ./.cert/cert.pem:/etc/nginx/.cert/cert.pem
            - ./.cert/key.pem:/etc/nginx/.cert/key.pem
        restart: 'unless-stopped'
        extra_hosts:
            - "host.docker.internal:host-gateway"  # 把host.docker.internal指向宿主机网关
        networks:
            - backend

networks:
    backend:
        driver: bridge

步骤4:重启服务

修改完配置后,重启Nginx容器:

docker-compose down && docker-compose up -d

验证

访问https://xxx.domain1.com/test和https://yyy.domain2.com/test,应该能正常转发到宿主机的3000/3001端口服务。如果还是有问题,检查宿主机防火墙是否允许容器访问3000/3001端口,以及证书文件是否正确挂载到容器内。

内容的提问来源于stack exchange,提问作者Edy Bourne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:45:24