Day-29.1-devops
Containerizing a MERN Stack Application with Docker Compose: A Comprehensive Guide
This guide provides a step-by-step approach to containerizing a MERN stack application using Docker Compose. It covers the architecture of a MERN stack, the creation of Dockerfiles for frontend and backend services, and the deployment process using Docker Compose, ensuring seamless communication between containers.
In this guide, we will explore how to containerize a MERN stack application and deploy it in a Docker environment using Docker Compose. If you're unfamiliar with the MERN stack, don't worry; we will cover its architecture and components in detail. By the end of this guide, you will learn how to write Dockerfiles for different services, set up a MongoDB database as a container, and deploy everything using Docker Compose.
Understanding the MERN Stack
What is the MERN Stack?
The MERN stack is a popular web development stack that consists of four main technologies:
MongoDB: A NoSQL database that serves as the data layer.
Express.js: A web application framework for Node.js that handles the backend logic.
React.js: A JavaScript library for building user interfaces, serving as the frontend layer.
Node.js: A JavaScript runtime that allows you to run JavaScript on the server side.
Three-Tier Architecture
The MERN stack follows a three-tier architecture, which includes:
Presentation Layer: The UI or frontend, where users interact with the application.
Business Logic Layer: The backend, where the application logic is processed.
Data Layer: The database, where data is stored and retrieved.
For example, in an e-commerce application like Amazon, the user interacts with the UI (frontend), which communicates with the backend (business logic) to fetch product details from the database (data layer).
Setting Up the Project
Before we dive into containerization, let's take a look at the project structure. We have two branches in our GitHub repository:
Main Branch: Contains the source code and instructions to run the application locally without Docker.
Compose Branch: Contains the Dockerfiles and Docker Compose setup that we will create in this guide.
Writing Dockerfiles
Frontend Dockerfile
To containerize the frontend, we will create a Dockerfile in the frontend directory. Here are the steps:
Start with the official Node.js image.
Set the working directory to
/app
.Copy the
package.json
file and install dependencies usingnpm install
.Copy the rest of the source code.
Expose the port that the application will run on (5173).
Define the command to run the application (
npm run dev
).
Backend Dockerfile
Similarly, we will create a Dockerfile for the backend:
Use the same Node.js image.
Set the working directory to
/app
.Copy the
package.json
file and install dependencies.Copy the source code.
Expose the backend port (5050).
Define the command to start the backend application (
npm start
).
Running MongoDB as a Container
Before running the backend, we need to start the MongoDB container. This can be done using the following command:
docker run --name mongodb -d -p 27017:27017 mongo:latest
This command runs MongoDB in detached mode and maps the default MongoDB port.
Creating a Docker Network
To allow communication between the frontend, backend, and database containers, we will create a Docker network:
docker network create mern-network
Running the Containers
After setting up the Dockerfiles and the MongoDB container, we can run the frontend and backend containers. Make sure to connect them to the same network:
docker run --name frontend --network mern-network -p 5173:5173 frontend-image
docker run --name backend --network mern-network -p 5050:5050 backend-image
Using Docker Compose
To simplify the process of running multiple containers, we will use Docker Compose. This allows us to define all services in a single YAML file. Here’s how to create a docker-compose.yml
file:
Docker Compose File Structure
Services: Define each service (frontend, backend, and MongoDB) with their respective configurations.
Networks: Specify the network that the services will use.
Volumes: Define any volumes needed for persistent data storage.
Example Docker Compose Configuration
version: '3'
services:
frontend:
build:
context: ./frontend
ports:
- "5173:5173"
networks:
- mern-network
backend:
build:
context: ./backend
ports:
- "5050:5050"
depends_on:
- mongodb
networks:
- mern-network
mongodb:
image: mongo:latest
ports:
- "27017:27017"
volumes:
- mongodb-data:/data/db
networks:
- mern-network
networks:
mern-network:
driver: bridge
volumes:
mongodb-data:
driver: local
Running Docker Compose
To start all services defined in the docker-compose.yml
file, simply run:
docker-compose up -d
This command will build and start all containers in detached mode, ensuring they are connected to the specified network.
Conclusion
In this guide, we have successfully containerized a MERN stack application using Docker Compose. We covered the architecture of the MERN stack, created Dockerfiles for the frontend and backend, set up a MongoDB container, and simplified the deployment process using Docker Compose. This approach not only streamlines development but also ensures that all components can communicate effectively within a defined network.
For further exploration, refer to the Compose branch in the GitHub repository for complete code and configurations. Thank you for following along, and happy coding!