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

docker run可正常运行镜像,docker-compose up报Nginx 404求助

问题描述

使用docker run -p 3000:3000单独运行Node.js镜像时,应用路由正常,浏览器可正常访问对应URL;但通过docker-compose up启动包含Node.js和Nginx的服务后,浏览器访问时返回Nginx 404错误。Node.js服务日志显示正常运行,但所有端点均无法访问。

Dockerfile(Node.js)

#Base Image node:12.18.4-alpine
FROM node:12.18.4-alpine

#Set working directory to /app
WORKDIR /InboundBackend

#Set PATH /app/node_modules/.bin
ENV PATH /InboundBackend/node_modules/.bin:$PATH

#Copy package.json in the image
COPY package.json ./

RUN npm install
RUN npm ci --only-production
#Copy the app
COPY . /InboundBackend/

EXPOSE 3000

##Start the app
# CMD ["ls"]
CMD ["npm", "start"]

Dockerfile(Nginx)

FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf

docker-compose.yaml

version: '3.8'

services:
  nodejs:
    build:
      context: .
      dockerfile: Dockerfile
    image: nodejs
    container_name: nodejs
    restart: unless-stopped
    ports:
      - "3000:3000"

  nginx:
    image: nginx:mainline-alpine
    container_name: webserver
    restart: unless-stopped
    build:
      context: ./nginx-conf
    ports:
      - "80:80"
      - "443:443"

Nginx配置(default.conf)

listen 80;
        listen [::]:80;


        #location ~ /.well-known/acme-challenge {
         #       allow all;
         #      root /var/www/html;
        #}

        #location / {
        #        rewrite ^ https://$host$request_uri? permanent;
        #}

        location /graphql {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_pass http://nodejs:3000;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }

        #location @Nodejs {
         #       proxy_pass http://Nodejs:3000;
         #      add_header X-Frame-Options "SAMEORIGIN" always;
         #     add_header X-XSS-Protection "1; mode=block" always;
         #       add_header X-Content-Type-Options "nosniff" always;
         #       add_header Referrer-Policy "no-referrer-when-downgrade" always;
         #       add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        #}

}
server {
       #  listen 443 ssl http2;
        # listen [::]:443 ssl http2;
        server_name api.***.com www.api.***.com;

        server_tokens off;

        # ssl_certificate /etc/letsencrypt/live/nodejs.devopslee.com/fullchain.pem;
        # ssl_certificate_key /etc/letsencrypt/live/nodejs.devopslee.com/privkey.pem;

        ssl_buffer_size 8k;



        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_prefer_server_ciphers on;

        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

        ssl_ecdh_curve secp384r1;
        ssl_session_tickets off;

        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8;


        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
}

排查与解决方案

1. 修复Nginx配置的语法错误

当前Nginx配置中第一个server块缺失开头的server {,导致配置解析失败,Nginx会自动使用默认配置,无法正确代理请求到Node.js服务。修复后的第一个server块应为:

server {
    listen 80;
    listen [::]:80;

    #location ~ /.well-known/acme-challenge {
    #       allow all;
    #      root /var/www/html;
    #}

    #location / {
    #        rewrite ^ https://$host$request_uri? permanent;
    #}

    location /graphql {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_pass http://nodejs:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }

    #location @Nodejs {
    #       proxy_pass http://Nodejs:3000;
    #      add_header X-Frame-Options "SAMEORIGIN" always;
    #     add_header X-XSS-Protection "1; mode=block" always;
    #       add_header X-Content-Type-Options "nosniff" always;
    #       add_header Referrer-Policy "no-referrer-when-downgrade" always;
    #       add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
    #}
}

2. 验证Nginx配置正确性

在Nginx容器内执行命令检查配置语法:

docker exec webserver nginx -t

输出显示test is successful则配置无语法问题,否则根据提示修正错误。

3. 检查服务间网络连通性

Docker Compose默认会创建桥接网络,服务间可通过服务名互通。在Nginx容器内ping Node.js服务验证连通:

docker exec webserver ping nodejs

若无法ping通,确认Docker Compose配置中两个服务在同一网络(默认已满足),或手动指定网络确保连通。

4. 调整请求路径代理规则

当前Nginx仅代理/graphql路径,若访问其他路径(如根路径/)会匹配到默认root目录/var/www/html,因无对应文件返回404。如需代理所有路径到Node.js,取消注释location / {块并修改为:

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://nodejs:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

5. 重启服务生效

修改配置后,重启Docker Compose服务:

docker-compose down && docker-compose up --build

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:00:26