How to Dockerize an Express.js App ?
Docker is an open-source containerization platform used for building, running, and managing applications in an isolated environment. A container is isolated from another and bundles its software, libraries, and configuration files. This article will discuss how to dockerize an Express app for the development and deployment phases.
Prerequisites: Before continuing any further, please ensure that node and docker are installed on your machine. If required visit Node Installation Guide or Docker Installation Guide.
Dockerized an Express application
For this tutorial, we will create a simple Node.js Express application, which will act as a REST API.
Step 1
Initialize an empty node project by running the following commands:
mkdir express-docker
cd express-docker
npm init -y
Step 2
Install express and create a new file index.js:
npm install express
touch index.js
Step 3
Paste the following into index.js:
const express = require('express'),
app = express();
app.use(express.urlencoded({ extended: true }))
app.use(express.json())
app.get('/',
(req, res) => res.send('Dockerizing Node Application'))
app.listen(5000,
() => console.log(`⚡️[bootup]: Server is running at port: 5000`));
Project Structure: This is how the project structure should look at this point.
Step 4
Start the server by running:
node index.js
Note
Now, if you go to the URL http://localhost:5000/ you’ll see the below output
Dockerfile for development: At the root of our react project create a Dockerfile for the development phase. Let’s name it Dockerfile.dev.
touch Dockerfile.dev
In the newly created file, paste the following commands:
# Fetching the minified node image on apline linux
FROM node:slim
# Declaring env
ENV NODE_ENV development
# Setting up the work directory
WORKDIR /express-docker
# Copying all the files in our project
COPY . .
# Installing dependencies
RUN npm install
# Starting our application
CMD [ "node", "index.js" ]
# Exposing server port
EXPOSE 5000
Create a .dockerignore file to exclude unnecessary files thus speeding up the build process.
node_modules
npm-debug.log
build
.git
*.md
.gitignore
Now create a docker image by using the docker build command
docker build -f Dockerfile.dev -t [name:tag] .
Here,
-
-f: Path to the docker file
-
-t: Name and tag for the image
-
.: The context for the build process
Once the build process has been completed, you will receive the id and tag of your new image.
Create a docker container by running:
docker run -d -it –-rm -p [host_port]:[container_port] –name [container_name] [image_id/image_tag]
Here,
-
-d: Run the container while printing the container ID.
-
-it: Create an interactive container
-
-p: Map host port to container port
-
-–name: Assign a name to the container
-
-–rm: When it leaves, take the container away automatically.
Verify whether the container has been created successfully by running:
docker container ps
Navigate to http://localhost:5000/ to verify the build process.
Dockerfile for production: The deployed application will crash or stop working when there is any unhandled exception or error in our server and we have to manually restart it by interacting with our docker container via the command-line interface. So, for the final step will install a process manager that will automatically restart the server and ensure everything runs smoothly in production. This is where PM2 comes into the picture. PM2 is an open-source, cross-platform production-level process manager that comes with a built-in load balancer.
Create a YAML file for PM2 at the root of our express application:
touch process.yml
Paste the following content into the process.yml file:
apps:
- script: index.js
instances: 4
exec_mode: cluster
Here, we are telling the PM2 to start four instances of our server in cluster mode.
Next, create a new Dockerfile for production mode:
touch Dockerfile
Paste the following commands:
# Fetching the minified node image on apline linux
FROM node:slim
# Declaring env
ENV NODE_ENV production
# Setting up the work directory
WORKDIR /express-docker
# Copying all the files in our project
COPY . .
# Installing dependencies
RUN npm install
# Installing pm2 globally
RUN npm install pm2 -g
# Starting our application
CMD pm2 start process.yml && tail -f /dev/null
# Exposing server port
EXPOSE 5000
Repeat the same steps to build an image from the updated Dockerfile and create a container out of it.
docker build -t [name:tag] .
docker run -d -it -–rm -p [host_port]:[container_port] –name [container_name] [image_id/image_tag]
Verify whether the container has been created successfully by running:
docker container ps
Project Structure: This is how the project structure should look at this point:
Open your browser and navigate to http://localhost:5000/ in your browser to view the dockerized express app.
Note
Please refer to the Dockerfile used in this tutorial if you are having any difficulties following the above steps.