NestJS生产环境Docker容器配置失败:npm找不到package.json排查
NestJS生产环境容器npm找不到package.json问题排查
问题背景
已成功搭建NestJS开发容器、MySQL及Redis容器,但配置生产环境容器时,npm始终无法在/usr/src/app路径下找到package.json,执行npm install或npm run build均报错。尝试过添加--chown=node:node参数、切换node用户等操作,问题仍未解决。
相关配置文件
docker-compose.yml
version: '3.8' networks: nesjs-network: driver: bridge services: redis: container_name: nestjs_redis image: redis environment: - ALLOW_EMPTY_PASSWORD=yes networks: - nesjs-network ports: - '${FORWARD_REDIS_PORT:-5003}:6379' dev: container_name: nestjs_dev image: nestjs-api-dev:1.0.0 build: context: ./Docker target: development dockerfile: Dockerfile command: npm run start:dev ports: - 3000:3000 - 9229:9229 networks: - nesjs-network volumes: - .:/usr/src/app - /usr/src/app/node_modules restart: unless-stopped env_file: '.env' depends_on: - database - redis links: - database - redis prod: container_name: nestjs_prod image: nestjs-api-prod:1.0.0 build: context: ./Docker target: production dockerfile: Dockerfile # command: npm run start:prod ports: - 3000:3000 - 9229:9229 networks: - nesjs-network volumes: - .:/usr/src/app - /usr/src/app/node_modules restart: unless-stopped env_file: '.env' depends_on: - database - redis links: - database - redis database: build: context: ./Docker dockerfile: mysql8.Dockerfile image: mysql/mysql-server:latest container_name: database restart: unless-stopped tty: true ports: - '${FORWARD_DB_PORT:-3306}:3306' env_file: '.env' command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --authentication_policy=mysql_native_password --host_cache_size=0 environment: MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' MYSQL_DATABASE: '${DB_NAME}' MYSQL_USER: '${DB_USER}' MYSQL_PASSWORD: '${DB_PASSWORD}' MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' TZ: '${APP_TIMEZONE-America/New_York}' networks: - nesjs-network volumes: - dbdata:/var/lib/mysql:rw,delegated #Volumes volumes: dbdata: driver: local
/docker/Dockerfile
################### # BUILD FOR LOCAL DEVELOPMENT ################### FROM node:18-alpine AS development WORKDIR /usr/src/app COPY package*.json ./ # RUN apk add --nocache udev ttf-freefont chromium git RUN apk add udev ttf-freefont chromium git ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true ENV CHROMIUM_PATH /usr/bin/chromium-browser RUN npm install -g npm@8.19.2 RUN npm install glob rimraf # RUN npm install --only=development RUN npm ci COPY . . # Nest line needs to be tested EXPOSE 3000 EXPOSE 9229 ################### # PRODUCTION ################### FROM node:18-alpine as production ARG NODE_ENV=production ENV NODE_ENV=${NODE_ENV} WORKDIR /usr/src/app COPY package*.json ./ RUN apk update \ && apk add ca-certificates wget \ && update-ca-certificates # RUN apk add --nocache udev ttf-freefont chromium git RUN apk add udev ttf-freefont chromium git ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true ENV CHROMIUM_PATH /usr/bin/chromium-browser # RUN npm install -g npm@8.19.2 # RUN npm install glob rimraf # RUN npm install --only=production RUN npm ci COPY . . EXPOSE 3000 EXPOSE 9229 COPY --from=development /usr/src/app/dist ./dist # RUN npm run build CMD ["node", "dist/main"]
报错日志
=> ERROR [build 7/8] RUN pm run build > [build 7/8] RUN nom run build: #0 0.518 pm ERR! code ENOENT #0 0.519 nom ERR! syscall open #0 0.519 pm ERR! path /usr/src/app/package.json #0 0.520 nom ERR! errno -2 #0 0.521 pm ERR! enoent ENOENT: no such file or directory, open '/usr/src/app/package.json' #0 0.521 pm ERR! enoent This is related to pm not being able to find a file. #0 0.521 pm ERR! enoent #0 0.522 #0 0.522 pm ERR! A complete log of this run can be found in: #0 0.522 nom ERR! /root/.npm/_logs/2022-10-15T19_02_39_449Z-debug-0.log failed to solve: executor failed running [/bin/sh -c pm run build]: exit code: 254
问题排查与修复
1. 构建上下文路径错误
docker-compose.yml中dev和prod服务的build.context设置为./Docker,导致Docker只能读取./Docker目录下的文件进行构建,但项目的package.json在根目录(与docker-compose.yml同级),所以构建时COPY package*.json ./找不到文件。
修复:
修改docker-compose.yml中两个服务的build配置,将上下文改为项目根目录,同时指定Dockerfile路径:
build: context: . target: development dockerfile: ./Docker/Dockerfile
2. 生产环境不必要的卷挂载
生产环境容器无需挂载本地目录,当前prod服务的volumes配置会覆盖容器内原有文件,导致路径混乱。
修复:
移除prod服务中的volumes配置块。
3. 命令拼写错误
报错日志中出现pm run build、nom run build,明显是npm的拼写错误,检查并修正构建命令。
4. 优化生产环境构建流程
当前生产阶段依赖开发阶段的dist目录,若开发阶段未提前构建,该目录不存在。可二选一优化:
- 方案一:在开发阶段构建
在Dockerfile的development阶段,COPY . .后添加:RUN npm run build - 方案二:在生产阶段自行构建
移除COPY --from=development /usr/src/app/dist ./dist,取消注释RUN npm run build:# COPY --from=development /usr/src/app/dist ./dist RUN npm run build
内容的提问来源于stack exchange,提问作者Christian De Santis
相关产品推荐
相关产品推荐

