With the help of Dockerfile, we can create custom Docker images.
Docker images can be very heavy in size. and when you try to install dependencies or code within it, size may increase drastically and we end up having a very large docker image.
Let’s see what can we do to optimize image generation and make it smaller in size.
Let’s suppose there is a PM2 (NodeJS) official docker image, on which I want to add my code and make it run.
FROM keymetrics/pm2:10-jessie as dependencies WORKDIR /home/ubuntu/demoproject COPY package.json . RUN npm install FROM keymetrics/pm2:10-alpine as app WORKDIR /home/ubuntu/demoproject COPY --from=dependencies /home/ubuntu/demoproject/node_modules node_modules ADD . . EXPOSE 3000 CMD [ "pm2-runtime", "start", "app.js" ]
In the above Dockerfile,
1. I’m taking keymetrics/pm2:10-jessie official image from here
2. Setting up a working directory as /home/ubuntu/demoproject
3. Copying package.json file within this temporary container.
– Jessie version is Debian 8 type and due to that, it can easily install all required packages with help of Debian as backend.
4. Run “npm install” to install required packages written on package.json file.
5. Now in the next steps, we are taking keymetrics/pm2:10-alpine image, which is very light in weight and is based on Alpine Linux
6. Setting up a working directory as /home/ubuntu/demoproject
7. Now we are copying node_modules from first image variation which we called as dependencies
8. Now, we can add code.
9. We exposed port 3000 for application
10. In last step, we are running app.js file as a final command.
In this example, if I haven’t used multistage concept and if I went with Jessie version thoroughly, the docker image’s size would be more than 1.2GB.
With multistage, for same code, image size reduced to 160MB
Drafted on: 17th March 2020
What is multi-stage Dockerfile?
How do I create a multi-stage Dockerfile?
What is multistage build?
Which is a benefit of using multistage builds with Docker?