Posted by : at

Category : nodejs   mongodb   react   docker


When your App depends on more containers, building images each time for each container, while in development to make any changes won’t help. That’s when docker-compose comes in to play ! Docker Compose helps in running multi-containered apps. And also you don’t have to build images. All your local changes can be synced with the containers. Let’s understand better by building a full-stack MERN App using docker-compose. In this tutorial we will be building a Blog App !


Let’s create a new folder for our Project, lets say “mern-docker”:

In this we will be creating two folders : api for backend and client for frontend. And our docker-compose file will be used to build our App. So our folder structure will be something like this:

 - mern-docker
 --api // node express mongodb server
 --client // react
 --docker-compose.yml

I can add everything in this post, So, You can find the source code from this github repo : https://github.com/sujaykundu777/mern-docker

Creating our Node Express Mongodb API Server :

We will create a new express app for our blog using this repo :

git clone https://github.com/sujaykundu777/blog-rest-api.git api

This will create a new folder api with our required express rest-api. Note in this folder you will find a Dockerfile. This is very important file for our setup, because this will be used by our Docker Compose.


Creating our React Client :

We will create a new react client for our blog using this repo :

git clone https://github.com/sujaykundu777/blog-react-client.git client

This will create a new folder client with our required express server.Note in this folder you will find a Dockerfile. This is very important file for our setup, because this will be used by our Docker Compose.

Creating our Docker Compose File :

Let’s now see our docker-compose file :

version: '3.7'

services:

  # REACT client
  react:
    build:
      context: ./client
      dockerfile: Dockerfile
    image: webapp-client
    container_name: react
    restart: always
    ports:
      - "80:80"
    volumes:
      - ./client:/var/www/app
    links:
      - node
    networks:
      - app-network

  # Express Server
  node:
    build:
      context: ./api
      dockerfile: Dockerfile
    image: webapp-server
    container_name: node
    restart: unless-stopped
    volumes:
      - ./api:/opt/node_app/app
      - /opt/node_app/app/node_modules
    ports:
      - "8080:8080"
    depends_on:
      - mongodb
    env_file: .env
    environment:
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=$MONGO_HOSTNAME
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB
    networks:
      - app-network

  # Mongodb database
  mongodb:
    image: mongo
    container_name: mongodb
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
      - MONGO_INITDB_DATABASE=$MONGO_DB
    volumes:
      - data-volume:/data/db
    ports:
      - "27017:27017"
    networks:
      - app-network

networks:
    app-network:
        driver: bridge

volumes:
    data-volume:
    node_modules:
    web-root:
      driver: local

So we got 3 services.

  1. React
  2. Node
  3. Mongodb

And this services are connected, via a network “app-network” and we have created volumes.

We need to create a .env file to store our Environment Variables in our app’s root directory:

MONGO_USERNAME=sammy
MONGO_PASSWORD=password
MONGO_HOSTNAME=mongodb
MONGO_PORT=27017
MONGO_DB=mern_docker_db

So Now, Let’s run our App :

docker-compose up

Now you can visit http://localhost:80, to get React Client

Now you can visit http://localhost:8080, to get Node Express Server