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.
Dockerizing 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:
Javascript
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:
Ruby
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.