Hey folks! π
If you've ever tried deploying a MERN stack app (MongoDB, Express, React, Node.js), youβve probably run into some challenges juggling all the services locally or in production. The solution? Docker Compose! π³
In this post, Iβll walk you through how to containerize a MERN stack app using Docker Compose and follow a 3-tier architecture: frontend (React), backend (Express + Node.js), and the database (MongoDB).
Letβs go! πͺ
π§ Why 3-Tier Architecture?
Before we get our hands dirty, here's how the MERN stack maps to a 3-tier system:
Presentation Layer β React.js (handles the UI)
Business Logic Layer β Node.js + Express (handles API logic and routing)
Data Layer β MongoDB (stores and retrieves data)
Keeping these layers separate helps in scaling, debugging, and managing services better. Plus, itβs how things work in production environments.
π Folder Structure
mern-app/ βββ backend/ β βββ Dockerfile β βββ server.js βββ frontend/ β βββ Dockerfile β βββ src/ βββ docker-compose.yml
π¨** Dockerizing Each Layer
π’οΈ MongoDB (Database Layer)**
Add this to your docker-compose.yml:
mongodb: image: mongo container_name: mongo ports: - "27017:27017" volumes: - mongo-data:/data/db
βοΈ Backend β Express + Node.js (Business Layer)
Dockerfile (/backend/Dockerfile)
FROM node:18 WORKDIR /app COPY . . RUN npm install EXPOSE 5000 CMD ["node", "server.js"]
Compose Service
backend: build: ./backend ports: - "5000:5000" environment: - MONGO_URI=mongodb://mongo:27017/mydb depends_on: - mongodb
π¨ Frontend β React.js (Presentation Layer)
Dockerfile (/frontend/Dockerfile)
Dockerfile
FROM node:18 WORKDIR /app COPY . . RUN npm install RUN npm run build RUN npm install -g serve CMD ["serve", "-s", "build", "-l", "3000"]
Compose Service
frontend: build: ./frontend ports: - "3000:3000" depends_on: - backend
π§© Final docker-compose.yml
version: '3' services: mongodb: image: mongo container_name: mongo ports: - "27017:27017" volumes: - mongo-data:/data/db backend: build: ./backend ports: - "5000:5000" environment: - MONGO_URI=mongodb://mongo:27017/mydb depends_on: - mongodb frontend: build: ./frontend ports: - "3000:3000" depends_on: - backend volumes: mongo-data:
π§ͺ Run the App
From the root of your project, just run:
docker-compose up --build
And thatβs it! Your MERN app is now running across 3 separate containers π
Frontend β http://localhost:3000
Backend API β http://localhost:5000
MongoDB β Running internally on port 27017
β
Wrapping Up
Docker Compose makes developing and deploying full-stack apps much more manageable. Whether you're working solo or on a team, containerizing your app ensures consistency and scalability across environments.
Let me know in the comments if you found this guide helpful or need help with any part of your setup. π
Top comments (1)
Need more of these!