Lightweight and Performance Dockerfile for Node.js

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

Nodenode:slimnode: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

Lightweight and Performance Dockerfile for Node.js
Dockerfile with node
Lightweight and Performance Dockerfile for Node.js
The image, based on node, weights 936 Mb

node:slim

Lightweight and Performance Dockerfile for Node.js
Dockerfile with node:slim
Lightweight and Performance Dockerfile for Node.js
The image, based on node:slim, weights 160 Mb

node:alpine

Lightweight and Performance Dockerfile for Node.js
Dockerfile with node:alpine
Lightweight and Performance Dockerfile for Node.js
The image, based on node:alpine, weights 109 Mb

alpine

Lightweight and Performance Dockerfile for Node.js
Dockerfile with alpine
Lightweight and Performance Dockerfile for Node.js
The image, based on apline, weights 5.58 Mb

Node.js

I can agree with you, that images nodenode: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:

Image for post
Dockerfile with alpine and node.js
Image for post
The image, based on apline with installed node.js, weights 56.3 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


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.