A Comprehensive Guide to Terragrunt: Getting Started and Exploring its Features Learn about Terragrunt, a powerful open-source tool for managing infrastructure as code using Terraform. Discover the advantages of using…
Lightweight and Performance Dockerfile for Node.js
Hello World! Today I’m about to share my knowledge about Dockerfile
for Node.js
applications. I hope you will find it useful and create a Lightweight and Performance Dockerfile for Node.js, which will suit all your needs.
How to create lightweight and performance Dockerfile especially for Node.js applications
If you are here it means, that you have faced Docker
before, but to be sure that we are on the same page let’s remind what it is.
So, there are no secrets — Dockerfile
is an instruction of how our image will be built. Step by step, layer by layer this file describes how our image will look like.
Okay, so another question — what is an image? We can treat it as a template. Once you build an image from your Dockerfile
, it can be shared with other people. You can run a container from an image.
The last but not the least — container, it’s a running image, the actual process.
Why do we need this system? It solves the particular problem — environment. You can run a container where you need to, regardless of your OS. So, as you can see everything begins from Dockerfile
.
FROM
First things first — FROM
. The command, which describes what will be used as a base for the container. We should keep in mind that we are building Node.js
Dockerfile
since we discuss it in the context of our article. Usually, you can meet the next approach:
FROM node
Also common are the next images:
FROM node:slim
and
FROM node:alpine
but I prefer another one:
FROM alpine
Node
, node:slim
, node:alpine
and alpine
are official images. You can read more about them on official pages. Okay, so what for and why? The reason here is the weight. So, if we use anode
image, we get 900+ Mb from the start, node:slim
gives 160 Md, node:alpine
— 109 Mb and at the same time only 5 Mb for alpine
.
node
node:slim
node:alpine
alpine
Node.js
I can agree with you, that images node
, node:slim
and node:alpine
are ready for usage, while alpine
is just a lightweight Linux and there is no Node.js
at all. Not a problem, let’s install it:
RUN apk add --update nodejs nodejs-npm
Now we have Node.js
and weight is still acceptable — 56 Mb:
WORKDIR
The step, which I would skip, cause you can find it in any tutorial and there is not much to talk about, but I have to. The folder, where our application will be located inside the container:
WORKDIR /app
package.json
Since each line of out Dockerfile
is a layer, Docker tries to cache it as much as possible, to increase building speed. It means, that commands, which change rarely, must be in the beginning. You remember that we already installed alpine
and Node.js
, the next thing, which changes rarely is package.json
. So let’s bring it:
COPY package*.json ./
Since we have set /app
as our work directory — everything we are coping will be saved to this folder.
npm
Now we have to install all our dependencies:
RUN npm install
I believe it’s pretty clear what for.
COPY source code
Our container is useless without a source code, so we need to copy it to our future image:
COPY . .
It should be noted, that this approach copies everything from the source to the target. To avoid unnecessary files and folder, for instance, /node_modules
we have to add it to .dockerignore
. It works the same as .gitignore
:
node_modules/
Standard commands
The following lines are common for most of Dockerfiles
and don’t need to be explained:
EXPOSE 5000CMD ["npm", "start"]
EXPOSE
– the container listens on the specified network ports at runtime.
CMD
– the command, which can be single for the Dockerfile
. It provides defaults for an executing container.
The result
Dockerfile
FROM alpineRUN apk add --update nodejs nodejs-npmWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .EXPOSE 5000CMD ["npm", "start"]
.dockerignore
node_modules/
With this Dockerfile
, you can build lightweight and performance images for Node.js
. I hope you found it useful and learned something new for you.
Offtop
The following information doesn’t belong to Dockerfile
, but it still Docker
field. There are a few commands, which help me from time to time. I believe it’s nice to add it to your toolkit.
Open a container via console:
docker exec -it container-id sh
Open an image via console:
docker run -it image-name sh