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.