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

Nginx反向代理Docker化Node.js应用子路径返回404求助

问题描述

我在Ubuntu服务器上部署了Docker化的Node.js应用,配置了GitHub CI/CD与Nginx反向代理。访问服务器IP可正常响应,但访问serverip/aboutpage时Nginx返回404;直接在服务器上用curl访问容器IP+端口的子路径(0.0.0.0:8080/aboutpage)可得到有效响应,本地运行一切正常。

相关配置文件

/etc/nginx/sites-available/default

root /var/www/html;

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

server_name _;

location / {
        proxy_pass http://172.17.0.2:8080; #docker container ip 
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
}

Dockerfile

FROM node:22-alpine

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

USER node

WORKDIR /home/node/app

COPY --chown=node:node package*.json .

RUN npm install

COPY --chown=node:node . .

EXPOSE 8080

CMD [ "node", "server.js" ]

.github/workflows/ci.yml

name: CI Pipeline

on:
  push:
    branches: [ "main" ]

jobs:

  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Login Dockerhub
      env:
        DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}}
        DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
      run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
    - name: Build the Docker image
      run: docker build -t sm-api .
    - name: Tag Docker local image
      run: docker tag sm-api username/sm-api:latest
    - name: Push to Dockerhub
      run: docker push username/sm-api:latest

.github/workflows/cd.yml

name: CD Pipeline

on:
  workflow_run:
    workflows: ["CI Pipeline"]
    types:
      - completed

jobs:

  build:

    runs-on: self-hosted

    steps:
    - name: Pull Docker image
      run: sudo docker pull username/sm-api:latest
    - name: Delete Old docker container
      run: sudo docker rm -f sm-api-container || true
    - name: Run Docker Container
      run: sudo docker run -d -p 8080:8080 --name sm-api-container username/sm-api

Node.js路由文件

function MyRoutes(app, express){
    const router = express.Router();
    router.get('/', (req, res) => {
        res.send('HomePage');
      });
    router.get('/about', (req, res) => {
        res.send('about');
      });
    
      return router;
}
module.exports = {
    WebRoutes
};

解决方案

1. 修复Nginx配置问题

当前Nginx配置中,try_files指令会优先尝试在本地服务器的/var/www/html目录下查找请求的文件或目录,找不到就直接返回404,不会将请求转发给Node.js容器。需要删除try_files,并添加必要的代理头信息,同时用容器名代替固定IP(避免容器重启后IP变化):

修改后的/etc/nginx/sites-available/default:

root /var/www/html;

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

server_name _;

location / {
        proxy_pass http://sm-api-container:8080;
        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;
}

修改后重启Nginx:

sudo systemctl restart nginx

2. 修复Node.js路由的导出与路径匹配问题

  • 路由函数定义为MyRoutes,但导出的是WebRoutes,导致路由无法正确加载,需保持名称一致;
  • 问题中访问的是/aboutpage,但路由里只有/about,需调整路由路径匹配访问地址:

修改后的路由文件:

function WebRoutes(app, express){
    const router = express.Router();
    router.get('/', (req, res) => {
        res.send('HomePage');
      });
    router.get('/aboutpage', (req, res) => {
        res.send('about');
      });
    
      return router;
}
module.exports = {
    WebRoutes
};

3. 重新部署应用

修改代码后推送至GitHub,触发CI/CD流程重新构建并部署容器,确保新的路由配置生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:27:28