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.
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 :
Now you can visit http://localhost:80, to get React Client
Now you can visit http://localhost:8080, to get Node Express Server