Project Overview
A production-ready, full-stack multi-service application built and orchestrated with Docker Compose. This project demonstrates a real-world microservices architecture, featuring a modern React frontend, a robust Node.js/Express API, MongoDB for data persistence, Redis for caching, and NGINX as a reverse proxy. It is designed for scalability, security, and developer productivity.
The application showcases essential Docker concepts including multi-container orchestration, Docker secrets management, custom Dockerfiles with multi-stage builds, persistent data storage, and development workflows with hot reload capabilities.
Architecture Highlights
- Frontend: React (Vite) SPA with modern UI/UX
- Backend: Node.js + Express RESTful API
- Database: MongoDB with persistent storage and initialization script
- Cache: Redis for performance and session management
- Reverse Proxy: NGINX for SSL termination, routing, and static file serving
- Docker Compose: Multi-container orchestration and networking
- Docker Secrets: Secure management of sensitive data (e.g., DB passwords)
- Log Rotation: Configured for all services to prevent disk overuse
- Health Checks: For all major services to ensure reliability
- Hot Reload: Enabled for local development with Docker Compose Watch
- Custom Dockerfiles: Multi-stage builds for optimized images
- Environment Variables: Centralized config for easy deployment
Service Architecture
[ NGINX ]
|
+---> [ Frontend (React) ]
|
+---> [ API (Node.js/Express) ]
| |
| +---> [ MongoDB ]
| +---> [ Redis ]
All services communicate over a private Docker network
(app-network).
NGINX handles all incoming HTTP requests and routes them to the appropriate service.
MongoDB and Redis use Docker volumes for persistent data.
Presentation Layer
Application Layer
Data Layer
Key Features
Containerized Services
Each service runs in isolated Docker containers with optimized multi-stage builds
Service Mesh
Internal communication through Docker networks with service discovery
Security Hardening
Non-root users, minimal base images, and secrets management
Health Monitoring
Container health checks and application monitoring with Prometheus
Load Balancing
Nginx reverse proxy with load balancing and SSL termination
Data Persistence
Persistent volumes for database storage and Redis caching
Security Implementation
Security was a primary consideration throughout the development process, implementing multiple layers of protection and following container security best practices.
Container Security
- Multi-stage Docker builds for minimal attack surface
- Non-root user execution in all containers
- Read-only root filesystems where possible
- Resource limits and constraints
- Security scanning with Trivy
Network Security
- Isolated Docker networks for service communication
- Nginx reverse proxy for external access
- SSL/TLS encryption for external connections
- Internal service-to-service authentication
- Firewall rules and port restrictions
Secrets Management
- Docker secrets for sensitive data
- Environment variable encryption
- Database credentials rotation
- API key management
- Vault integration for production deployment
Technical Implementation
Docker Compose Configuration
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./project/dist:/usr/share/nginx/html
depends_on:
- frontend
- api
networks:
- app-network
frontend:
build:
context: ./project
dockerfile: Dockerfile
volumes:
- ./project:/app
- /app/node_modules
networks:
- app-network
develop:
watch:
- action: sync
path: ./project/src
target: /app/src
api:
build:
context: ./api
dockerfile: Dockerfile
environment:
- NODE_ENV=development
- MONGO_URI=mongodb://mongodb:27017/multiservice
- REDIS_URL=redis://redis:6379
secrets:
- mongo_root_password
depends_on:
- mongodb
- redis
networks:
- app-network
volumes:
- ./api:/app
- /app/node_modules
develop:
watch:
- action: sync
path: ./api
target: /app
mongodb:
image: mongo:latest
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/mongo_root_password
secrets:
- mongo_root_password
volumes:
- mongo_data:/data/db
- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js
networks:
- app-network
ports:
- "27023:27017"
redis:
image: redis:alpine
volumes:
- redis_data:/data
networks:
- app-network
ports:
- "6379:6379"
networks:
app-network:
driver: bridge
volumes:
mongo_data:
redis_data:
secrets:
mongo_root_password:
file: ./secrets/mongo_root_password.txt
Security-Hardened Dockerfile
# Multi-stage build for security and size optimization
FROM node:18-alpine AS builder
# Create app directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production && npm cache clean --force
# Copy source code
COPY . .
# Build application
RUN npm run build
# Production stage
FROM node:18-alpine AS production
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodeuser -u 1001
# Set working directory
WORKDIR /app
# Copy built application from builder stage
COPY --from=builder --chown=nodeuser:nodejs /app/dist ./dist
COPY --from=builder --chown=nodeuser:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodeuser:nodejs /app/package*.json ./
# Install security updates
RUN apk update && apk upgrade && \
apk add --no-cache dumb-init && \
rm -rf /var/cache/apk/*
# Switch to non-root user
USER nodeuser
# Expose port
EXPOSE 5000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node healthcheck.js
# Use dumb-init for proper signal handling
ENTRYPOINT ["dumb-init", "--"]
# Start application
CMD ["node", "dist/server.js"]
Monitoring & Observability
Comprehensive monitoring setup provides insights into application performance, resource utilization, and system health.
Health Checks
Automated health monitoring for all services with automatic restart capabilities
Metrics Collection
Prometheus scrapes metrics from all services including custom application metrics
Alerting
Configured alerts for high CPU usage, memory consumption, and service failures
Visualization
Grafana dashboards for real-time monitoring and historical trend analysis
Deployment & CI/CD
The project includes automated deployment pipelines and CI/CD configuration for seamless development and production deployments.
Code Commit
Developer pushes code to repository triggering automated pipeline
Testing & Security Scan
Automated tests run along with container security scanning
Image Building
Docker images built and pushed to container registry
Deployment
Automated deployment to staging/production environments
Getting Started
Follow these steps to run the multi-service application locally:
1Prerequisites
2Clone Repository
git clone https://github.com/IbraheemA05/Multi-Service-Docker-Application.git
cd Multi-Service-Docker-Application
3Environment Setup
# Copy environment template
cp .env.example .env
# Create secrets directory and add MongoDB password
mkdir -p secrets
echo "your_secure_mongo_password" > secrets/mongo_root_password.txt
4Build and Run
# Clean build and start services
docker compose down -v
docker compose build --no-cache
docker compose up
# Access the application
# Frontend: http://localhost/
# API: http://localhost:5001/api
# MongoDB: localhost:27023
# Redis: localhost:6379
Learning Outcomes
This project provided comprehensive hands-on experience with modern containerization technologies and DevOps practices.
Container Technologies
- Docker containerization best practices
- Multi-stage build optimization
- Container orchestration with Docker Compose
- Volume and network management
Security Practices
- Container security hardening
- Secrets management implementation
- Network security configuration
- Vulnerability scanning integration
Database & Caching
- MongoDB database integration
- Redis caching implementation
- Data persistence with Docker volumes
- Database initialization scripts
DevOps Integration
- CI/CD pipeline design
- Automated testing integration
- Infrastructure as Code principles
- Production deployment strategies