How to Put Express.js in Docker in 2 minutes

How to put Express.js in Docker in 2 minutes

Share This Post

If you need to put express.js in docker, that is, dockerize your Express.js app, look no further. For the ones who are familiar with docker, just use the following dockerfile. Otherwise, we have an explanation of it line-by-line below.

FROM node:12

WORKDIR /usr/src/app

COPY package*.json ./
COPY index.js ./
COPY .babelrc ./
COPY src ./src
COPY node_modules ./node_modules

EXPOSE 80
CMD ["npm", "run", "start"]

Express.js in Docker Explained

We have three main parts in this dockerfile that realize help us dockerize our express.js app. First, we need to prepare the container from the right parent. Then, we need to copy all the files of our application. Finally, we expose it for external access.

Prepare the Container

With the first two lines, we prepare the container.

FROM node:12
WORKDIR /usr/src/app

Here, we start by extending the Node.js container – a Debian-based Linux image that comes with Node.js included. We can pick the version of Node that we prefer, as the version of the image corresponds to the Node.js version. So, in this example, we are going with Node.js version 12.

The other line is about specifying the working directory, the place where we will execute any other command from here onward. We are specifying /usr/src/app because this is where the Node.js server would like to have the files of our applications. In other words, the original container image with Node expects us to put the application there. Even if, technically, we could place it somewhere else, this is the recommended practice.

Copying the Express.js app inside Docker

Now, we need to copy our app inside the container image. All the following lines, combined, will do so.

COPY package*.json ./
COPY index.js ./
COPY .babelrc ./
COPY src ./src
COPY node_modules ./node_modules

We expect to build this container image on a machine that has Node.js also installed, and that also has installed our Express.js application (with npm install). We start by copying both package.json and package-lock.json, thanks to the star wildcard character in the first line. We then proceed to copy our entry-point index.js, and since in our case we are using Babel also our .babelrc file. Then, we copy all our source folder and all our node_modules folder.

This is why it’s important to have installed our app in the local machine before building the container image. Otherwise, the node_modules folder will be empty and our container will lack dependencies.

Alternatively, we could run npm install inside the container as a command, but this would not work in case we use private NPM registries. To make it work in that case, we would need to ship authentication credentials inside our docker image and remove them later, a cumbersome and risky process.

Exposing the Container

Now, the container image contains our app. We need to take just one final step to expose it.

EXPOSE 80
CMD ["npm", "run", "start"]

With these two lines, we first say that the container will listen on port 80, enabling incoming HTTP. Then, we say that, by default, when we launch the container it should run npm run start, which in our package.json must be defined as the command that starts express.js.

Our best practice here is to expose containers and internal services on port 80. Then, we can put an NGINX load balancer in front of them to expose them over the Internet using HTTPS. In this way, our container will be more lightweight and will not have to deal with SSL certificates.

In a Nutshell

Express.js and Docker are two powerful technologies. Combining them together is a no-brainer way to success.

As we just saw, it is easy to put Express.js in Docker. With that simple dockerfile, you can do that literally in seconds. Obviously, you will need an existing Express.js app to dockerize. If you are starting out, we have a good tutorial on Express.js as well that you should check out.

Picture of Alessandro Maggio

Alessandro Maggio

Project manager, critical-thinker, passionate about networking & coding. I believe that time is the most precious resource we have, and that technology can help us not to waste it. I founded ICTShore.com with the same principle: I share what I learn so that you get value from it faster than I did.
Picture of Alessandro Maggio

Alessandro Maggio

Project manager, critical-thinker, passionate about networking & coding. I believe that time is the most precious resource we have, and that technology can help us not to waste it. I founded ICTShore.com with the same principle: I share what I learn so that you get value from it faster than I did.

Alessandro Maggio

2021-04-30T16:30:00+00:00

Unspecified

DevOps

Unspecified