10 - Docker Practical Examples

Docker Practical Examples

Previously we covered Docker fundamentals: commands, image builds, data management, networking, Compose, production best practices, and troubleshooting. Here are real-world cases to show how to apply Docker in projects.

Case 1: Deploy a web application

Scenario

Deploy a Node.js-based web app with frontend, backend API, and MongoDB.

Solution

1. Create project structure

my-web-app/
├── frontend/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
├── backend/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
└── docker-compose.yml

2. Frontend Dockerfile

# frontend/Dockerfile
FROM node:14-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

3. Backend Dockerfile

# backend/Dockerfile
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "src/index.js"]

4. Docker Compose config

# docker-compose.yml
version: '3'

services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - app-network

  backend:
    build: ./backend
    ports:
      - "3000:3000"
    environment:
      - MONGO_URI=mongodb://mongodb:27017/myapp
    depends_on:
      - mongodb
    networks:
      - app-network

  mongodb:
    image: mongo:4.4
    volumes:
      - mongo-data:/data/db
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  mongo-data:

5. Start the app

docker-compose up -d

Benefits

  • Consistent environments across dev/test/prod
  • Simple deployment: one command brings up the stack
  • Component isolation: services run independently
  • Data persistence: MongoDB data stored in a named volume

Case 2: WordPress blog platform

Scenario

Quickly deploy a WordPress blog with a MySQL database.

Solution

Docker Compose config

version: '3'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress_password
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress_data:/var/www/html
    depends_on:
      - db
    restart: always

  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress_password
    restart: always

volumes:
  wordpress_data:
  db_data:

Start WordPress

docker-compose up -d

Visit http://localhost:8080 to complete WordPress installation.

Benefits

  • Rapid deployment: spin up WordPress in minutes
  • Data persistence: named volumes for WordPress files and DB data
  • Easy maintenance: upgrade WordPress/MySQL easily
  • Portability: run anywhere Docker is available

Case 3: CI/CD pipeline

Scenario

Build a CI/CD pipeline with Docker to automate testing and deployment.

Solution

1. Dockerfile for test environment

# Dockerfile.test
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "test"]

2. Jenkins pipeline config

// Jenkinsfile
pipeline {
  agent {
    docker {
      image 'node:14-alpine'
    }
  }
  stages {
    stage('Build') {
      steps {
        sh 'npm install'
      }
    }
    stage('Test') {
      steps {
        sh 'npm test'
      }
    }
    stage('Build Docker Image') {
      steps {
        sh 'docker build -t myapp:${BUILD_NUMBER} .'
      }
    }
    stage('Deploy') {
      steps {
        sh 'docker-compose -f docker-compose.prod.yml up -d'
      }
    }
  }
}

3. Production Docker Compose config

# docker-compose.prod.yml
version: '3'

services:
  app:
    image: myapp:${BUILD_NUMBER}
    ports:
      - "80:3000"
    environment:
      - NODE_ENV=production
    restart: always

Benefits

  • Environment consistency: tests and prod use the same Docker image
  • Automation: build, test, deploy automatically
  • Versioning: each build creates a uniquely tagged image
  • Easy rollback: revert to previous images quickly

Case 4: Microservices architecture

Scenario

Deploy an app with multiple microservices: API gateway, user service, product service, and databases.

Solution

Docker Compose config

version: '3'

services:
  api-gateway:
    build: ./api-gateway
    ports:
      - "80:8000"
    depends_on:
      - user-service
      - product-service
    networks:
      - microservice-network

  user-service:
    build: ./user-service
    environment:
      - DB_HOST=user-db
    depends_on:
      - user-db
    networks:
      - microservice-network

  product-service:
    build: ./product-service
    environment:
      - DB_HOST=product-db
    depends_on:
      - product-db
    networks:
      - microservice-network

  user-db:
    image: postgres:13
    volumes:
      - user-db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=user_service
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=users
    networks:
      - microservice-network

  product-db:
    image: postgres:13
    volumes:
      - product-db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=product_service
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=products
    networks:
      - microservice-network

networks:
  microservice-network:
    driver: bridge

volumes:
  user-db-data:
  product-db-data:

Benefits

  • Service isolation: each microservice runs in its own container
  • Independent scaling: scale specific services as needed
  • Tech diversity: different services can use different stacks
  • Simplified deployment: manage the whole architecture with Compose

Case 5: Data analytics environment

Scenario

Set up a data analytics environment with Jupyter Notebook, PostgreSQL, and visualization tools.

Solution

Docker Compose config

version: '3'

services:
  jupyter:
    image: jupyter/datascience-notebook
    ports:
      - "8888:8888"
    volumes:
      - ./notebooks:/home/jovyan/work
    environment:
      - JUPYTER_ENABLE_LAB=yes
    networks:
      - data-network

  postgres:
    image: postgres:13
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./init-scripts:/docker-entrypoint-initdb.d
    environment:
      - POSTGRES_USER=analyst
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=analytics
    networks:
      - data-network

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    depends_on:
      - postgres
    networks:
      - data-network

networks:
  data-network:
    driver: bridge

volumes:
  postgres-data:
  grafana-data:

Benefits

  • All-in-one environment: processing, storage, and visualization tools together
  • Reproducibility: consistent analytics environment
  • Data persistence: volumes store data and results
  • Easy sharing: share the environment config with teammates

Case 6: Standardized development environment

Scenario

Provide a standardized dev environment so the whole team uses the same tools and configs.

Solution

Create a dev-environment Dockerfile

# Dockerfile.dev
FROM ubuntu:20.04

# Install base tools
RUN apt-get update && apt-get install -y \
    git \
    curl \
    wget \
    vim \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - \
    && apt-get install -y nodejs

# Install Python
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    && rm -rf /var/lib/apt/lists/*

# Install dev tools
RUN npm install -g nodemon typescript
RUN pip3 install pytest flake8

WORKDIR /workspace

CMD ["bash"]

Use Docker Compose to manage the dev environment

# docker-compose.dev.yml
version: '3'

services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/workspace
      - node_modules:/workspace/node_modules
    ports:
      - "3000:3000"
      - "9229:9229"
    command: bash
    stdin_open: true
    tty: true

volumes:
  node_modules:

Start the dev environment

docker-compose -f docker-compose.dev.yml up -d
docker-compose -f docker-compose.dev.yml exec dev bash

Benefits

  • Consistent environments for all developers
  • Fast onboarding for new team members
  • Isolation from the host system
  • Version-controlled environment configuration

Summary

These six cases show how Docker applies to different scenarios—from web apps to microservices, from CI/CD to data analytics. They illustrate how to use Docker for consistent, reliable solutions. Use these patterns to apply Docker effectively in your own projects.

Found an issue with this content?

Tell us what could be improved.