Docker多阶段构建问题:Node服务未运行,React应用可正常访问
问题原因
你的Dockerfile采用了多阶段构建,但Docker默认只会使用最后一个阶段生成的镜像创建容器,第一个阶段的Node后端代码、依赖和启动命令完全没有被包含到最终运行的容器中,因此后端服务根本没启动。
解决方案
推荐采用拆分前后端为独立容器的方案,符合Docker「单容器单进程」的最佳实践,便于后续维护和扩容。
步骤1:调整项目结构
将前后端代码分离到独立目录,示例结构:
your-project/ ├── backend/ │ ├── package.json │ ├── server.js │ └── ... ├── frontend/ │ ├── package.json │ ├── src/ │ └── ... └── docker-compose.yml
步骤2:编写后端Dockerfile(backend/Dockerfile)
FROM node:12.6 WORKDIR /usr/src/app COPY package.json . RUN npm install COPY . . EXPOSE 5500 CMD ["npm", "run", "server"]
步骤3:编写前端Dockerfile(frontend/Dockerfile)
FROM node:12.6 WORKDIR /usr/src/app COPY package.json . RUN npm install COPY . . EXPOSE 3000 CMD ["npm", "run", "dev"]
步骤4:修改docker-compose.yml
version: "3.9" services: backend: container_name: testingApp-backend build: ./backend ports: - "5500:5500" # 可选:挂载代码实现热更新 # volumes: # - ./backend/src:/usr/src/app/src:delegated frontend: container_name: testingApp-frontend build: ./frontend volumes: - ./frontend/src:/usr/src/app/src:delegated ports: - "3000:3000" # 确保后端先启动 depends_on: - backend
步骤5:前端请求后端的配置
前端代码中不要用localhost:5500访问后端,改用Docker Compose内部服务名backend,比如:
// 示例请求 fetch('http://backend:5500/api/data') .then(res => res.json()) .then(data => console.log(data))
如果是Create React App创建的项目,还可以在frontend/package.json中添加代理配置,简化请求路径:
"proxy": "http://backend:5500"
这样前端直接请求/api/data即可自动转发到后端。
不推荐的方案:单容器运行多进程
如果一定要在同一个容器中运行两个服务,需要借助进程管理器(如pm2),但这种方式不利于问题排查和服务扩容,仅作参考:
- 在项目根目录创建pm2配置文件
ecosystem.config.js:
module.exports = { apps: [ { name: 'backend', script: 'npm', args: 'run server', cwd: '/usr/src/app/backend' }, { name: 'frontend', script: 'npm', args: 'run dev', cwd: '/usr/src/app/frontend' } ] };
- 编写合并后的Dockerfile:
FROM node:12.6 WORKDIR /usr/src/app # 复制前后端package.json COPY backend/package.json ./backend/ COPY frontend/package.json ./frontend/ # 安装依赖 RUN cd backend && npm install RUN cd frontend && npm install # 复制所有代码 COPY backend ./backend/ COPY frontend ./frontend/ # 安装pm2 RUN npm install -g pm2 # 暴露端口 EXPOSE 5500 3000 COPY ecosystem.config.js . CMD ["pm2-runtime", "start", "ecosystem.config.js"]
- 修改docker-compose.yml映射两个端口:
version: "3.9" services: testingapp: container_name: testingApp build: . volumes: - ./backend/src:/usr/src/app/backend/src:delegated - ./frontend/src:/usr/src/app/frontend/src:delegated ports: - "3000:3000" - "5500:5500"
内容的提问来源于stack exchange,提问作者njouro
相关产品推荐
相关产品推荐

