Docker and Node.js: Simplifying Development with MongoDB

The development and deployment of applications can be greatly simplified with Docker. Docker containers offer several advantages for developers:

  • Consistent environments: You can select the languages and dependencies you want without worrying about system conflicts.
  • Isolated environments: This makes debugging and onboarding new team members easier.
  • Portability: The code can be packaged and easily shared.

In this article, I will show you how to set up a development environment for a Node.js application using Docker. We will create two containers: one for the Node.js application and another for the MongoDB database. Among other things, you will:

  • Synchronize the application code with the code in the container to facilitate changes during development.
  • Ensure that changes are applied without restarting the application.
  • Create a password-protected database that is persistent.

By the end of this tutorial, a shark information application will be running in Docker containers.

Prerequisites

To follow this tutorial, you will need:

  • A development server running Ubuntu 18.04 and a non-root user with sudo privileges.
  • Docker and Docker Compose installed.

Step 1 – Clone the project and modify dependencies

The first step is to clone the sample code and modify the package.json file. We will add nodemon to the development dependencies so the application automatically restarts when you make changes.

First, clone the repository:

 
git clone https://github.com/do-community/nodejs-mongo-mongoose.git node_project
cd node_project

Open the package.json file:

Add nodemon under the dependencies:

 
"devDependencies": {
  "nodemon": "^1.18.10"
}

Save and close the file.

Step 2 – Adapt the application for containers

Now we will modify the code so that it works better with containers. We will use Node.js’s process.env property to dynamically work with environment variables.

Open app.js and modify the port as follows:

 
const port = process.env.PORT || 8080;
app.listen(port, function () {
  console.log(`App is listening on port ${port}`);
});

Also, modify the database connection in db.js to avoid hardcoding sensitive information:

 
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

Create a .env file with the necessary environment variables:

And add the following content (with your values):

 
MONGO_USERNAME=username
MONGO_PASSWORD=password
MONGO_PORT=27017
MONGO_DB=sharkinfo

Ensure that .env is included in both .gitignore and .dockerignore to prevent sensitive data from being uploaded.

Step 3 – Modify database connection settings

Add additional options in db.js to handle connection failures:

 
const options = {
  useNewUrlParser: true,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 500,
  connectTimeoutMS: 10000,
};
mongoose.connect(url, options).then(() => {
  console.log('MongoDB is connected');
}).catch(err => {
  console.log(err);
});

Step 4 – Define services with Docker Compose

Now we create the docker-compose.yml file to define the services. The first service is for the Node.js application:

 
version: '3'

services:
  nodejs:
    build:
      context: .
      dockerfile: Dockerfile
    image: nodejs
    container_name: nodejs
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=db
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB
    ports:
      - "80:8080"
    volumes:
      - .:/home/node/app
      - node_modules:/home/node/app/node_modules
    networks:
      - app-network
    command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js

The second service is for the MongoDB database:

 
  db:
    image: mongo:4.1.8-xenial
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
    volumes:
      - dbdata:/data/db
    networks:
      - app-network

Finally, add the network and volume definitions:

 
networks:
  app-network:
    driver: bridge

volumes:
  dbdata:
  node_modules:

Step 5 – Test the application

Start the application with:

Check the logs with:

If everything runs correctly, you should be able to see your application on your server’s URL.

Conclusion

By following this guide, you have learned how to develop and run a Node.js application with MongoDB in a Docker environment. Docker makes it easier to isolate your environment, secure your data, and seamlessly share your applications.

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in:

centron Managed Cloud Hosting in Deutschland

Docker Introduction: Containers Made Easy

Docker, Tutorial
Docker Introduction: Containers Made Easy Learn how to efficiently manage your applications with Docker. From installation to setting up a private registry server, this guide covers everything you need to…