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

Docker容器中Nginx无法接收请求的问题排查与解决

问题:Nginx容器无法接收请求,浏览器提示无法连接

将React应用基于nginx:alpine镜像部署到Docker容器后,访问对应URL时浏览器提示“无法连接”,执行docker logs -f nginx看不到任何请求日志,推测Nginx未接收到请求。

相关配置信息

docker-compose.yml中的Nginx配置

nginx:
    container_name: best-nginx
    build:
      context: .
    restart: always
    image: nginx:alpine
    volumes:
      - ./nginx/default.conf:/etc/nginx/default.conf
      - ./certs:/etc/nginx/certs
    ports:
      - "443:443"

Nginx的default.conf配置

server {
    root /usr/share/nginx/html;
    index index.html index.htm index.nginx-debian.html;

    server_name myservername.com;

    location / {
            try_files $uri $uri/ =404;
    }

    location /keycloak {
            proxy_pass http://localhost:28080/;
    }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/nginx/certs/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/nginx/certs/privkey.pem; # managed by Certbot
}

Dockerfile内容

# develop stage
FROM node:18-alpine as develop-stage
WORKDIR /app
COPY package*.json ./
COPY tsconfig.json ./
RUN npm install
COPY ./public ./public
COPY ./src ./src

# build stage
FROM develop-stage as build-stage
RUN npm run build

# production stage
FROM nginx:1.23.1-alpine as production-stage
COPY --from=build-stage /app/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

Docker日志输出

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/10/07 09:56:33 [notice] 1#1: using the "epoll" event method
2022/10/07 09:56:33 [notice] 1#1: nginx/1.23.1
2022/10/07 09:56:33 [notice] 1#1: built by gcc 11.2.1 20220219 (Alpine 11.2.1_git20220219) 
2022/10/07 09:56:33 [notice] 1#1: OS: Linux 5.15.0-48-generic
2022/10/07 09:56:33 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/10/07 09:56:33 [notice] 1#1: start worker processes
2022/10/07 09:56:33 [notice] 1#1: start worker process 32

原因分析与解决方案

1. Docker Compose镜像配置冲突,自定义镜像未生效

你的docker-compose配置同时指定了image: nginx:alpine和build: context: .,Docker会优先使用官方nginx:alpine镜像,而非你通过Dockerfile构建的包含React静态文件的自定义镜像,导致Nginx容器内没有你的应用文件,且可能覆盖了部分配置。

解决方法:

  • 删除image: nginx:alpine字段,让Docker Compose使用构建的自定义镜像;或者明确指定自定义镜像名称,比如image: my-react-nginx:latest,确保构建和运行的是同一镜像。

修改后的docker-compose.yml片段:

nginx:
    container_name: best-nginx
    build:
      context: .
    restart: always
    volumes:
      - ./nginx/default.conf:/etc/nginx/default.conf
      - ./certs:/etc/nginx/certs
    ports:
      - "443:443"

2. Nginx server_name与访问域名不匹配

配置中server_name myservername.com;,如果访问时用的是IP、localhost或其他未匹配的域名,Nginx找不到对应server块处理请求,会直接拒绝或忽略请求,自然不会生成日志。

解决方法:

  • 本地测试时,将server_name改为localhost _;(_匹配任何域名):
    server_name localhost _;
    
  • 线上环境确保访问域名与server_name完全一致,或添加通配符如*.myservername.com覆盖子域名。

3. SSL证书异常导致连接失败

如果./certs目录下的fullchain.pem、privkey.pem不存在、权限错误或证书无效,浏览器会因SSL握手失败无法连接,且这类握手失败的请求可能不会被Nginx记录到日志中。

解决方法:

  • 检查证书文件:执行ls -l ./certs确认文件存在,且权限为可读(可临时执行chmod 644 ./certs/*.pem调整);
  • 本地测试可临时注释SSL配置,改用HTTP协议验证:
    修改default.conf:
    server {
        root /usr/share/nginx/html;
        index index.html index.htm index.nginx-debian.html;
    
        server_name localhost _;
    
        location / {
                try_files $uri $uri/ /index.html; # React单页应用建议改为/index.html,避免刷新404
        }
    
        # 注释SSL配置,改用HTTP
        # listen [::]:443 ssl ipv6only=on;
        # listen 443 ssl;
        # ssl_certificate /etc/nginx/certs/fullchain.pem;
        # ssl_certificate_key /etc/nginx/certs/privkey.pem;
        listen 80;
    }
    
    同时修改docker-compose.yml端口映射为- "80:80",重启容器后访问http://localhost测试。

4. 宿主机端口占用或防火墙拦截

宿主机443端口可能被其他服务占用,或防火墙阻止了443端口的流量,导致请求根本无法到达Docker容器。

解决方法:

  • 检查端口占用:Linux执行netstat -tulpn | grep 443,Windows执行netstat -ano | findstr :443,确认端口是否被占用;
  • 临时关闭宿主机防火墙测试,或添加允许443端口的规则;
  • 临时更换端口,比如docker-compose.yml中改为- "8443:443",访问https://localhost:8443测试。

5. 反向代理配置的localhost指向错误(次要)

Nginx配置中proxy_pass http://localhost:28080/;的localhost是容器内部的localhost,而非宿主机。如果Keycloak运行在宿主机或其他容器,这个配置会导致Nginx无法连接Keycloak,但不会影响React应用的基础访问,不过建议修正:

  • Keycloak在其他Docker容器时,使用容器名称作为域名(如http://keycloak:28080/,需确保两个容器在同一Docker网络);
  • Keycloak在宿主机时,使用宿主机IP或host.docker.internal(Docker Desktop环境)。

验证步骤

  1. 执行docker-compose build --no-cache重新构建镜像,确保自定义镜像包含React静态文件;
  2. 执行docker-compose up -d启动容器;
  3. 执行docker inspect best-nginx查看容器网络配置和端口映射是否正确;
  4. 在宿主机执行curl -v https://localhost(或对应域名/端口),查看请求详细过程,确认是否能连接到Nginx。

内容的提问来源于stack exchange,提问作者Octavian Niculescu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:30:14