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

React Frontend Vite + Modern UI/UX
NGINX Proxy SSL Termination & Routing

Application Layer

Node.js/Express API RESTful API

Data Layer

MongoDB Persistent Storage
Redis Cache Session Management

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

docker-compose.yml
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

backend/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.

1

Code Commit

Developer pushes code to repository triggering automated pipeline

2

Testing & Security Scan

Automated tests run along with container security scanning

3

Image Building

Docker images built and pushed to container registry

4

Deployment

Automated deployment to staging/production environments

Getting Started

Follow these steps to run the multi-service application locally:

2Clone Repository

Terminal
git clone https://github.com/IbraheemA05/Multi-Service-Docker-Application.git
cd Multi-Service-Docker-Application

3Environment Setup

Configuration
# 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

Docker Commands
# 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