I want to dockerize my nestjs api. With the config listed below, the image gets 319MB big. What would be a more simple way to reduce the image size, than multi staging?
Dockerfile
FROM node:12.13-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
CMD npm start
.dockerignore
.git
.gitignore
node_modules/
dist/
A Docker image takes up more space with every layer you add to it. Therefore, the more layers you have, the more space the image requires. Each RUN instruction in a Dockerfile adds a new layer to your image. That is why you should try to do file manipulation inside a single RUN command.
For reducing docker image size you can use
While using multi-stage build you should have 2(or more) FROM directives, as usual, the first stage does build, and the second stage just copies build from the first temporary layer and have instructions for run the app. In our case, we should copy dist & node_modules directories.
The second important moment its correctly split dependencies between 'devDependencies' & 'dependencies' in your package.json file.
After you install deps in the first stage, you should use npm prune --production for remove devDependencies from node modules.
FROM node:12.14.1-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . ./
RUN npm run build && npm prune --production
FROM node:12.14.1-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/dist /app/dist
COPY --from=build /app/node_modules /app/node_modules
EXPOSE 3000
ENTRYPOINT [ "node" ]
CMD [ "dist/main.js" ]
If you have troubles with node-gyp or just want to see - a full example with comments in this gist:
https://gist.github.com/nzvtrk/cba2970b1df9091b520811e521d9bd44
More useful references:
https://docs.docker.com/develop/develop-images/multistage-build/
https://docs.npmjs.com/cli/prune
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With