MERN stack explanation + example with docker
The MERN stack is a popular combo of technologies used to build full-stack web applications. It’s made up of four main parts:
- MongoDB – A NoSQL database that stores data in a flexible, JSON-like format. It’s perfect for handling lots of data or complex relationships.
- Express.js – A web framework for Node.js that simplifies building backend logic, APIs, and handling server requests/responses.
- React – A JavaScript library for building user interfaces. It focuses on creating dynamic, interactive views for users.
- Node.js – A runtime that lets you run JavaScript on the server side.
Together, they provide a seamless way to create modern web apps. React handles the front-end (what users see), while Express and Node manage the back-end (server-side logic). MongoDB stores the app’s data, and it all works in JavaScript, making it super developer-friendly.
It’s like a one-stop shop for web development! BUT like every framework it has cons and pro’s
The cons and the pro’s
The MERN stack has its ups and downs. On the pro side, it’s JavaScript all the way through, making it easier for developers to work on both the front and back end without needing to switch languages. It’s also highly flexible, allowing you to create everything from small apps to large-scale projects. Plus, with React’s efficient rendering and MongoDB’s ability to handle unstructured data, it’s great for modern, dynamic applications.
The MERN stack—combining MongoDB, Express.js, React, and Node.js—offers a seamless, JavaScript-driven ecosystem ideal for building modern, scalable web applications with a unified language, flexible data handling, and efficient performance from backend to frontend.
On the downside, managing all these parts together can be tricky, especially for beginners. Scaling can also get complex if your app grows quickly, as MongoDB isn’t always the best for relational data. And while flexibility is great, it can mean there’s no clear “one way” to do things, which might slow down development for some teams.
The MERN stack may not be the best choice if your project requires relational databases, server-side rendering out of the box, or if your team lacks proficiency in JavaScript.
Fortunately for us, we use this stack as an API and not as a full blown server/backend language
The Importance of RESTful APIs in MERN Applications
In MERN applications, RESTful APIs play a crucial role as the communication bridge between the frontend and backend. They enable seamless data exchange, maintain a stateless architecture, and support scalable development, making them an essential component of modern web applications.
What Makes REST Tick?
REST, or Representational State Transfer, is guided by principles like stateless communication, a clear separation between client and server, and the use of uniform interfaces. Following these principles ensures APIs are consistent, efficient, and easy to maintain, which is key to building robust applications in the MERN stack.
setting op MERN stack
Prerequisites
Before we begin, make sure you have the following installed on your system:
- Docker (Download here)
- Docker Compose (Download here)
- Node.js & npm (Download here)
install all the following packages to move forward
npm install express mongoose cors
Your folder should look like this

For this example, we will assume the following structure for our MERN application:
mern-app/
|-- backend/ (Node.js + Express API)
|-- frontend/ (React App)
|-- docker-compose.yml
|-- Dockerfile (for backend)
|-- .env
Backend – Creating a Dockerfile
We first need to containerize our Node.js + Express backend by creating a Dockerfile
inside the backend/
directory.
backend/Dockerfile
# Use an official Node.js runtime as a parent image
FROM node:18-alpine
# Set the working directory in the container
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application code
COPY . .
# Expose the application port
EXPOSE 5000
# Start the server
CMD ["npm", "start"]
Frontend – Creating a Dockerfile
To containerize the React frontend, create a Dockerfile
inside the frontend/
directory.
frontend/Dockerfile
# Use an official Node.js runtime as a parent image
FROM node:18-alpine
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the app
COPY . .
# Build the React app
RUN npm run build
# Install a simple web server
RUN npm install -g serve
# Expose port 3000
EXPOSE 3000
# Serve the application
CMD ["serve", "-s", "build", "-l", "3000"]
Creating a Docker Compose File
Now that both backend and frontend Dockerfiles are set up, let’s define Docker Compose to orchestrate the services.
docker-compose.yml
version: '3.8'
services:
mongodb:
image: mongo:latest
container_name: mongo_container
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
backend:
build: ./backend
container_name: backend_container
restart: always
depends_on:
- mongodb
ports:
- "5000:5000"
environment:
MONGO_URI: mongodb://admin:password@mongodb:27017/
frontend:
build: ./frontend
container_name: frontend_container
restart: always
depends_on:
- backend
ports:
- "3000:3000"
volumes:
mongo_data:
Running the MERN Stack with Docker Compose
Once the Dockerfile
and docker-compose.yml
are set up, you can start the MERN stack by running the following command in the project root directory:
docker-compose up -d --build
This command builds the images and starts the containers in detached mode (-d
).
Verifying the Setup
After running the above command, verify that everything is running correctly:
docker ps
You should see mongo_container
, backend_container
, and frontend_container
running.
To access your application:
- Frontend: http://localhost:3000
- Backend: http://localhost:5000
- MongoDB: Connected internally via
mongodb://admin:password@mongodb:27017/
Conclusion
Dockerizing your MERN stack application provides a consistent environment for development and deployment. With Docker Compose, managing multi-container applications becomes seamless. This guide provided a step-by-step approach to containerizing a MERN stack and running it with Docker Compose.
Next Steps you can do
- Push the Docker images to Docker Hub for easy deployment.
- Deploy the application using Kubernetes for scalability.
- Use NGINX as a reverse proxy to streamline the deployment.