Posted by : at

Category : devops   node   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

Related Posts