DEV Community

Cover image for Dockerizing an Express App with MongoDB Database
Rakib Hasan
Rakib Hasan

Posted on

Dockerizing an Express App with MongoDB Database

In this blog post, we'll walk through the process of dockerizing an Express.js application with a MongoDB database. We'll create Docker images, set up a Docker Compose file, and run the application using Docker Compose.

Step 1: Set Up the Project Files

  1. Create Project Structure

    In the root of your project directory, express-mongo-docker, create the following files:

express-mongo-docker/
├── Dockerfile
├── .dockerignore
├── package.json
├── server.js
├── docker-compose.yml
└── config/
    ├── mongodb.js
    └── config.env

Enter fullscreen mode Exit fullscreen mode
  1. Express App Code

Add the Express server code in file index.js

const express = require('express');
const app = express();
const dotenv = require('dotenv');
const cors = require('cors');
const bodyParser = require('body-parser');
const connectDatabase = require('./config/mongoDb');
const port = process.env.PORT || 5000;

//setting up config file
dotenv.config({ path: 'config/config.env' });

// middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(bodyParser.urlencoded({ extended: true }));

// handle uncaught excepion

process.on('uncaughtException', (err) => {
  console.log(`ERROR: ${err.message} \n ${err.stack}`);
  console.log('Shutting down the server due to uncaught exception');
  process.exit(1);
});

// console.log(a); // reference error: uncaught error

// connecting to Database
connectDatabase();


// Api routes
app.get('/', (req, res) => {
  res.json({
    message: 'API is running',
    docker: 'Docker is running'
  });
});



const server = app.listen(port, () => {
  console.log(
    `Server is running at port ${port} in ${process.env.NODE_ENV} mode`
  );
});

// Handle unhandle Promise rejection

process.on('unhandledRejection', (err) => {
  console.log(`ERROR : ${err.message}`);
  console.log('Shutting down the server due to unhandle promise rejection');
  server.close(() => {
    process.exit(1);
  });
});

Enter fullscreen mode Exit fullscreen mode
  1. Connection To Mongodb Connecting to Mongodb database from file ./config/mongoDb
const mongoose = require('mongoose');

const connectDatabase = async () => {
  console.log('db uri', process.env.DB_LOCAL_URI);
  try {
    await mongoose.connect(process.env.DB_LOCAL_URI).then((con) => {
      console.log(
        `MongoDb database connected with host: ${con.connection.host}`
      );
    });
    console.log('MongoDB is connected');
  } catch (error) {
    console.log('MongoDB connection failed', error);
  }
};

module.exports = connectDatabase;
Enter fullscreen mode Exit fullscreen mode
  1. Add env file Create .env file from file: ./config/config.env
DB_LOCAL_URI=mongodb://<your-username>:<your-password>@mongo:27017/test-app?authSource=admin
MONGO_INITDB_ROOT_USERNAME=<your-username>
MONGO_INITDB_ROOT_PASSWORD=<your-password>
Enter fullscreen mode Exit fullscreen mode

Step 2. Creating Docker Images

First, let's create a Dockerfilefor our Express application:

# Use the official Node.js image as the base image
FROM node:18-alpine

# Set the working directory
WORKDIR /app

COPY package*.json ./

RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the port the app runs on
EXPOSE 5000

# Command to run the application
CMD ["npm", "run", "dev"]
Enter fullscreen mode Exit fullscreen mode

Next, create a .dockerignore file to exclude unnecessary files and directories:

node_modules
npm-debug.log
.git
.gitignore
.dockerignore
Dockerfile
docker-compose.yml
Enter fullscreen mode Exit fullscreen mode

Modify package.json scripts with Express and Mongoose:

"scripts": {
    "start": "node index.js",
    "dev": "SET NODE_ENV=DEVELOPMENT& nodemon -L index.js --host",
    "prod": "SET NODE_ENV=PRODUCTION& nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
Enter fullscreen mode Exit fullscreen mode

Step 3. Creating a Docker Compose File

Now, let's create a docker-compose.yml file to define and run our multi-container Docker application:

version: '3.8'

services:
  # MongoDB service
  mongo:
    image: mongo:latest
    container_name: mongo-container
    ports:
      - '27017:27017'
    volumes:
      - mongotestData:/data/db
    networks:
      - app-network
  # For environment variable it'll be beter if you use env file path here
    environment:
      - MONGO_INITDB_ROOT_USERNAME=<your-username>
      - MONGO_INITDB_ROOT_PASSWORD=<your-password>

  # Backend service
  backend:
    build:
      context: .
      dockerfile: Dockerfile
    image: mern-backend-image
    container_name: mern-backend-container
    ports:
      - '5000:5000'
    depends_on:
      - mongo
    env_file:
      - ./config/config.env
    stdin_open: true
    volumes:
      - .:/app
      - /app/node_modules
    networks:
      - app-network

# Define volumes
volumes:
  mongotestData:

# Define networks
networks:
  app-network:

Enter fullscreen mode Exit fullscreen mode

This Docker Compose file defines two services:

  • backend: Our Express application
  • mongo: MongoDB database

The backend service builds from our Dockerfile, maps port 5000, and depends on the mongo service. We also set an environment variable for the MongoDB connection string.

The mongo service uses the official MongoDB image, maps port 27017, and uses a named volume to persist data.( you can also bind local file path to store mongo data)

Step 4. Running the Application

To run the application using Docker Compose, follow these steps:

  1. Open a terminal and navigate to your project directory.
  2. Build and start the containers:
docker-compose up --build
Enter fullscreen mode Exit fullscreen mode
  1. Your application should now be running. Access it at http://localhost:5000.
  2. To stop the application, use:
docker-compose down
Enter fullscreen mode Exit fullscreen mode

Congratulations !!!

We've successfully dockerized an Express application with a MongoDB database. This setup allows for easy deployment and scaling of your application. Remember to adjust the configuration as needed for your specific project requirements.

Happy coding!

Top comments (0)