Docker构建Next.js镜像成功但运行报错:找不到node_modules状态文件
问题描述
基于Next.js模板创建的项目默认使用Yarn 3.5.1,执行docker build可成功构建镜像,但运行容器时报错:
Usage Error: Couldn't find the node_modules state file - running an install might help (findPackageLocation)
原Dockerfile内容如下:
# Stage 1: Build FROM node:18-alpine AS builder WORKDIR /app COPY .yarn ./.yarn COPY .yarnrc.yml ./ COPY package.json yarn.lock ./ RUN yarn install --immutable COPY . . RUN yarn build # Stage 2: Run FROM node:18-alpine WORKDIR /app COPY --from=builder /app/next.config.js ./ COPY --from=builder /app/public ./public COPY --from=builder /app/.next ./.next COPY --from=builder /app/.yarn ./.yarn COPY --from=builder /app/.yarnrc.yml ./ COPY --from=builder /app/package.json ./package.json COPY --from=builder /app/yarn.lock ./yarn.lock ENV NODE_ENV=production EXPOSE 3000 CMD ["yarn", "start"]
解决方案
方案1:补充复制Yarn 3 PnP必需文件
Yarn 3的--immutable安装会生成PnP加载器文件和依赖状态文件,这些是运行阶段的必要文件,需添加到Stage 2的复制步骤中:
修改后的Stage 2代码:
# Stage 2: Run FROM node:18-alpine WORKDIR /app # 新增复制PnP加载器与状态文件 COPY --from=builder /app/.pnp.cjs ./ COPY --from=builder /app/.pnp.loader.mjs ./ COPY --from=builder /app/.yarn/build-state.yml ./.yarn/ # 若使用了unplugged类型依赖,需同步复制该目录 COPY --from=builder /app/.yarn/unplugged ./.yarn/unplugged COPY --from=builder /app/next.config.js ./ COPY --from=builder /app/public ./public COPY --from=builder /app/.next ./.next COPY --from=builder /app/.yarn ./.yarn COPY --from=builder /app/.yarnrc.yml ./ COPY --from=builder /app/package.json ./package.json COPY --from=builder /app/yarn.lock ./yarn.lock ENV NODE_ENV=production EXPOSE 3000 CMD ["yarn", "start"]
方案2:在运行阶段执行生产依赖安装
若不想手动梳理所有Yarn状态文件,可在运行阶段执行生产环境的依赖安装,确保依赖状态完整:
修改后的Stage 2代码:
# Stage 2: Run FROM node:18-alpine WORKDIR /app COPY --from=builder /app/.yarn ./.yarn COPY --from=builder /app/.yarnrc.yml ./ COPY --from=builder /app/package.json ./package.json COPY --from=builder /app/yarn.lock ./yarn.lock # 执行生产环境依赖安装 RUN yarn install --immutable --production COPY --from=builder /app/next.config.js ./ COPY --from=builder /app/public ./public COPY --from=builder /app/.next ./.next ENV NODE_ENV=production EXPOSE 3000 CMD ["yarn", "start"]
方案3:切换到传统node_modules模式(兼容旧场景)
修改项目根目录的.yarnrc.yml,让Yarn生成传统的node_modules目录,之后在运行阶段复制该目录即可:
- 修改
.yarnrc.yml:
nodeLinker: node-modules
- 修改Dockerfile的Stage 2:
# Stage 2: Run FROM node:18-alpine WORKDIR /app COPY --from=builder /app/next.config.js ./ COPY --from=builder /app/public ./public COPY --from=builder /app/.next ./.next COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package.json ./package.json COPY --from=builder /app/yarn.lock ./yarn.lock ENV NODE_ENV=production EXPOSE 3000 CMD ["yarn", "start"]
内容的提问来源于stack exchange,提问作者EshgheCode
相关产品推荐
相关产品推荐

