I'm trying to set up a multi-stage Docker build for my Node.js and Nest.js application. The Dockerfile includes installing dependencies, building the application, and running it. However, I'm encountering an issue with the npm run build command in the production stage of the Dockerfile.
Here's a simplified version of my Dockerfile:
# Use node base image with tag 18-slim
FROM node:18-slim as base
# Set NODE_ENV environment variable to production
ENV NODE_ENV=production
# Expose port 3000
EXPOSE 3000
# Create app directory and set permissions
WORKDIR /app
RUN chown -R node:node /app
# Switch to non-root user
USER node
# Copy package.json and package-lock.json
COPY --chown=node:node package*.json ./
# Install dependencies
RUN npm ci && npm cache clean --force
# Set PATH environment variable in dev stage
ENV PATH /app/node_modules/.bin:$PATH
# Copy source code
COPY --chown=node:node . .
# Development stage
FROM base as dev
# Set NODE_ENV environment variable to development
ENV NODE_ENV=development
# Command to run development server
CMD ["npm", "run", "start:dev"]
# Production stage
FROM base as prod
# Build production code
RUN npm run build
# Command to run production server
CMD ["node", "dist/main.js"]
The error message I'm getting is:
sh: 1: nest: not found
It seems that the Nest.js CLI is not available in the PATH during the production build, even though it's installed as a dev dependency in my package.json.
#11 [prod 1/2] RUN ls /app/node_modules/.bin
#11 0.152 acorn
#11 0.152 color-support
#11 0.152 highlight
#11 0.152 js-yaml
#11 0.152 mime
#11 0.152 mkdirp
#11 0.152 node-pre-gyp
#11 0.152 nopt
#11 0.152 opencollective
#11 0.152 semver
#11 0.152 sha.js
#11 0.152 ts-node
#11 0.152 ts-node-cwd
#11 0.152 ts-node-esm
#11 0.152 ts-node-script
#11 0.152 ts-node-transpile-only
#11 0.152 ts-script
#11 0.152 tsc
#11 0.152 tsserver
#11 0.152 typeorm
#11 0.152 typeorm-ts-node-commonjs
#11 0.152 typeorm-ts-node-esm
#11 0.152 uuid
#11 DONE 0.2s
How can I ensure that the Nest.js CLI is available in the PATH during the production build in my Dockerfile?
Rev2
The following instruction in
basestage renders/app/node_modules/.bin/nestunavailable.But in the current configuration of Dockerfile, because
basestage is meant for bothdevandprod, including dev dependencies will not sit well forprodstage.Now, I suggest the following to remedy the situation:
ENV NODE_ENV=productionandRUN npm cifrombasestage, making this stage free from preparing dev/prod dependencies.ENV NODE_ENV=developmentandRUN npm citodevstage.ENV NODE_ENV=productionandRUN npm citoprodstage.Docker has a nice Dockerfile example on this matter.
https://docs.docker.com/language/nodejs/develop/#update-your-dockerfile-for-development
Rev1
See if changing
/dev/node_modules/.binto/app/node_modules/.binresolves the issue.At
basestage, instructionWORKDIR /appset the working directory for the following instructions likeRUNto be performed at/app, so that following instructionRUN npm installcreates/app/node_modules.But later on, at
devandprodstage, instructionsENV PATHinclude a path/dev/node_modules/.bin, which contradicts the setup inbasestage.