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

Docker部署Node.js+PM2搭配Nginx反向代理出现502错误排查

问题根源分析

你遇到502错误的核心原因是Docker多阶段构建的逻辑错误:
你的Dockerfile最后阶段基于nginx:alpine镜像,这意味着第一个build阶段的Node应用启动指令(CMD ["pm2-runtime", ...])被完全覆盖了——最终运行的容器里只有Nginx在工作,Node应用根本没有启动。Nginx试图代理到localhost:3000,但这个端口上没有任何服务在监听,所以返回502 Bad Gateway。


解决方案

方案一:用Docker Compose分离Node应用和Nginx(推荐,符合容器单职责原则)

1. 调整Node应用的Dockerfile

删除多阶段构建的Nginx部分,只保留Node+PM2的构建逻辑:

FROM node:14.17.0

WORKDIR /usr/app

RUN npm install --global pm2

ENV PM2_PUBLIC_KEY xxxxx
ENV PM2_SECRET_KEY xxxxx

COPY ./package*.json ./
RUN npm install

COPY ./ ./
RUN npm run-script build

EXPOSE 3000

CMD [ "pm2-runtime", "start", "npm", "--", "start" ]

2. 创建docker-compose.yml文件

通过Compose管理两个独立容器(Node应用和Nginx代理):

version: '3.8'

services:
  node-app:
    build: .
    container_name: node-app
    expose:
      - 3000

  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "3000:80"
    volumes:
      - ./.nginx/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - node-app

3. 修改Nginx配置的代理目标

把proxy_pass的localhost:3000改成Docker Compose服务名node-app:3000(Docker内部DNS会自动解析到Node容器):

location / {
    proxy_pass http://node-app:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}

4. 启动服务

执行命令:

docker-compose up -d

方案二:将Node和Nginx放在同一个容器(不推荐,仅用于快速验证)

如果你想临时在一个容器里运行两个服务,可以修改Dockerfile,用启动脚本同时启动Node和Nginx:

FROM node:14.17.0 AS build

WORKDIR /usr/app

RUN npm install --global pm2

ENV PM2_PUBLIC_KEY xxxxx
ENV PM2_SECRET_KEY xxxxx

COPY ./package*.json ./
RUN npm install

COPY ./ ./
RUN npm run-script build

FROM nginx:alpine

# 安装Node.js(与构建阶段版本匹配)
RUN apk add --no-cache nodejs npm

# 复制Node应用文件
COPY --from=build /usr/app /usr/app
WORKDIR /usr/app

# 安装PM2
RUN npm install --global pm2

# 复制Nginx配置
COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf

# 创建启动脚本,同时启动PM2和Nginx
RUN echo '#!/bin/sh' > /start.sh && \
    echo 'pm2-runtime start npm -- start &' >> /start.sh && \
    echo 'nginx -g "daemon off;"' >> /start.sh && \
    chmod +x /start.sh

EXPOSE 3000 80

ENTRYPOINT ["/start.sh"]

启动命令

注意将主机端口映射到容器的80端口(Nginx监听端口):

docker run -d -p 3000:80 test/test

验证方法

可以通过以下命令确认问题:

  1. 查看容器日志:docker logs <容器ID>,会看到Nginx报错connect() failed (111: Connection refused) while connecting to upstream
  2. 进入容器检查端口:docker exec -it <容器ID> sh,安装net-tools后执行netstat -tulpn,会发现3000端口没有任何进程监听

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:06:27