Simplified Deployment: Containerizing Node.js and MongoDB with Docker

Seamless Containerization for Beginners

Introduction:

In this sample project, we will create a simple Node.js application that saves user information (username, email, and contact) in a MongoDB database. We will then containerize this application using Docker and deploy it on a local machine.

Prerequisites:

  1. Login to your docker hub account.

1. Creating the Node.js Application

I’ve created a simple Node.js application for this demo purpose. You can find the source code on GitHub: node-app-test

Set Up Your Project:

Create a new directory for your project and navigate into it using your terminal or command prompt.

Initialize Node.js Project:

Run the following command to initialize a new Node.js project. This will create a package.json file with default settings:

npm init -y

This command assumes default settings for the package.json file. You can customize the settings interactively if needed.

Create app.js file and copy following code:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const path = require('path');

const app = express();
const PORT = 3000;

// Set up Handlebars as the view engine
app.engine('handlebars', exphbs.engine());
app.set('view engine', 'handlebars');

// Set up body-parser middleware
app.use(bodyParser.urlencoded({ extended: true }));

// Connect to localhost MongoDB
mongoose.connect('mongodb://localhost/user-input-app', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

// Dynamic connection
// mongoose.connect(process.env.MONGODB_URI, {
//   useNewUrlParser: true,
//   useUnifiedTopology: true,
// });

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

// Define the User schema
const userSchema = new mongoose.Schema({
  name: String,
  email: String,
  phoneNumber: String,
});

const User = mongoose.model('User', userSchema);

// Define routes
app.get('/', (req, res) => {
  res.render('home', { layout: 'main' });
});

app.get('/user-form', (req, res) => {
  res.render('user-form', { layout: 'main' });
});

app.post('/submit', (req, res) => {
  const { name, email, phoneNumber } = req.body;

  const newUser = new User({ name, email, phoneNumber });

  newUser.save()
    .then(() => {
      res.render('success', { layout: 'main' });
    })
    .catch((err) => {
      console.error(err);
      res.render('error', { layout: 'main' });
    });
});

// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));

// Start the server
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
Install Dependencies:

Open a terminal or command prompt, navigate to your project directory, and install the required dependencies using npm (Node Package Manager). Run the following command:

npm install express mongoose body-parser express-handlebars path
Start MongoDB:

Ensure that MongoDB is installed and running locally on your machine. If not, you can download and install MongoDB from the official website.

Start MongoDB by running mongod in your terminal.

Run the Application:

Once the dependencies are installed, you can run the application using Node.js. In the terminal, run the following command:

node app.js

This command starts the Node.js server, and you should see a message indicating that the server is running on http://localhost:3000


Test the Application:

Open a web browser and navigate to http://localhost:3000 to access the home page of your Node.js application.

You can interact with the application by navigating to different routes, such as /user-form, and submitting user information.

Verify MongoDB Connection:

Ensure that MongoDB is running locally on your machine. The Node.js application is configured to connect to MongoDB running at mongodb://localhost/user-input-app.

Make sure MongoDB is running and accessible at this URI.

Now that we’ve confirmed the application works seamlessly on our local setup, it’s time to containerize it with Docker !!


2. Dockerizing the Application

To containerize our Node.js application, we’ve created a Dockerfile. This Dockerfile specifies the environment and dependencies required to run our application within a Docker container. You can find the Dockerfile in the GitHub repository mentioned above.

FROM node:18.18.0

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

Steps:

  1. Build the Docker Image

Use the docker build command to build a Docker image from your Dockerfile.

docker build -t <image_name> .

Replace <image_name> with the desired name for your Docker image.

2. Verify the Docker Image

After building the Docker image, you can verify that it was created successfully by running

docker images

This command lists all Docker images on your system, and you should see the image you just built listed there.


3. Deploying Locally

After building the Docker image for our application, we tested it locally on our machine to ensure everything worked as expected. This step is crucial for verifying that our application behaves correctly within a containerized environment.

1. Run a Docker Container from the Image

Once the Docker image is built, you can run a container from it using the docker run command. For example:

docker run -p <host_port>:<container_port> <image_name>

Replace <host_port> and <container_port> with the port mappings required by your application. If your Node.js application runs on port 3000 inside the container, you might use -p 3000:3000.

2. Access the Application

Open a web browser or use a tool like cURL to access your application running in the Docker container. If your application is a web server, navigate to http://localhost:<host_port> to interact with it.

NOTE: To create a customized Docker image and push it to DockerHub, please refer to this informative blog post


Next Steps

In the upcoming blog post, we’ll explore how to deploy our containerized Node.js application on a Kubernetes (K8s) cluster using a Continuous Integration/Continuous Deployment (CI/CD) pipeline.

Stay tuned for the next installment!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top