DevOps Shack - 10 Docker Projects To Master Docker
DevOps Shack - 10 Docker Projects To Master Docker
DevOps Shack
10 Docker Projects to Master Docker:
Basic to Advanced
Table of Contents
(Beginner)
1. Basic Web Application with Docker
2
(Advanced)
6. Secure Docker Deployment with Traefik and Let's Encrypt
3
Introduction
Docker has revolutionized the way applications are developed, deployed, and
managed. By leveraging containerization, developers can ensure consistency
across different environments, improve application scalability, and enhance
overall deployment efficiency. Whether you are a beginner looking to get
started or an experienced developer aiming to refine your skills, hands-on
projects are the best way to gain a deep understanding of Docker.
This document presents 10 practical projects that will help you master Docker,
covering everything from basic containerization to advanced deployment
strategies. Starting with fundamental concepts such as running a simple web
application in a container, you will progress through multi-container
applications, persistent storage, networking, scaling, security, and automation.
Each project is carefully designed to introduce key Docker features and best
practices while providing real-world applications for practical learning.
By the end of this document, you will have built a solid foundation in Docker,
learned how to efficiently manage containerized applications, and gained
experience with orchestration tools like Docker Swarm and Kubernetes. These
projects will not only enhance your technical expertise but also prepare you for
real-world challenges in DevOps and cloud-native application development.
Let's dive into the projects and begin our journey to mastering Docker!
4
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello, Docker!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
2. Write a Dockerfile
o Create a Dockerfile in the project root:
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
3. Build & Run the Docker Image
o Build the Docker image:
docker build -t flask-app .
o Run the container:
docker run -p 5000:5000 flask-app
4. Verify the Application
o Open http://localhost:5000 in your browser.
5
2. Multi-Container Application with Docker Compose
Goal: Learn how to manage multi-container applications using Docker
Compose.
Tech Stack:
Flask/Node.js
PostgreSQL/MySQL
Docker Compose
Implementation Steps:
1. Set Up Web Application & Database
o Create a simple web application with a database connection (Flask
+ PostgreSQL).
o Example app.py:
import psycopg2
from flask import Flask
app = Flask(__name__)
def connect_db():
return psycopg2.connect(
dbname="mydb",
user="user",
password="password",
host="db"
)
@app.route("/")
def home():
6
conn = connect_db()
return "Connected to DB!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
2. Create a Dockerfile
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
3. Create docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
depends_on:
- db
db:
image: postgres
environment:
POSTGRES_USER: user
7
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
4. Run with Docker Compose
docker-compose up --build
5. Verify Connection
o Open http://localhost:5000 in your browser.
8
3. Custom Docker Images & CI/CD Pipeline
Goal: Automate Docker image builds and deployments with CI/CD.
Tech Stack:
GitHub Actions/GitLab CI
Docker Hub
Flask/Node.js
Implementation Steps:
1. Set Up a GitHub Repository
o Push your Dockerized app to GitHub.
2. Create a GitHub Actions Workflow (.github/workflows/docker.yml)
name: Docker Build & Push
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
9
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{
secrets.DOCKER_USERNAME }}" --password-stdin
10
4. Docker Swarm & Load Balancing
Goal: Deploy a scalable, load-balanced web app using Docker Swarm.
Tech Stack:
Docker Swarm
Nginx
Flask/Node.js
Implementation Steps:
1. Initialize Swarm
docker swarm init
2. Create docker-compose.yml for Swarm
yaml
CopyEdit
version: '3.8'
services:
web:
image: myusername/myapp:latest
deploy:
replicas: 3
restart_policy:
condition: any
ports:
- "5000:5000"
nginx:
image: nginx
ports:
11
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
3. Deploy to Swarm
docker stack deploy -c docker-compose.yml myapp
4. Verify Load Balancing
o Access http://localhost and see requests being balanced.
12
5. Kubernetes with Docker
Goal: Orchestrate Docker containers using Kubernetes.
Tech Stack:
Kubernetes
Flask/Node.js
Minikube
Implementation Steps:
1. Start Minikube
minikube start
2. Create a Kubernetes Deployment (deployment.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web-app
13
image: myusername/myapp:latest
ports:
- containerPort: 5000
3. Create a Service (service.yaml)
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 5000
type: LoadBalancer
4. Deploy to Kubernetes
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
5. Verify Deployment
kubectl get pods
kubectl get services
6. Access the App
o Run minikube service web-service to get the URL.
Final Thoughts
14
These projects cover all major Docker concepts:
✅ Basic Containerization
✅ Multi-Container Applications
✅ CI/CD Automation
✅ Swarm for Scaling
✅ Kubernetes for Orchestration
By the end of these projects, you'll be confident in real-world Docker
deployments! 🚀
15
6. Monitoring and Logging with Docker (Advanced)
Goal: Set up monitoring and logging for Docker containers using Prometheus,
Grafana, and the ELK stack (Elasticsearch, Logstash, Kibana).
Tech Stack:
Prometheus (Monitoring)
Grafana (Visualization)
ELK Stack (Logging)
Docker Compose
Implementation Steps:
Step 1: Set Up a Sample Web Application
Create a simple Flask or Node.js application that logs messages.
Flask Example (app.py)
from flask import Flask
import logging
app = Flask(__name__)
# Configure logging
logging.basicConfig(filename='app.log', level=logging.INFO)
@app.route("/")
def home():
app.logger.info("Home route accessed")
return "Monitoring Docker App"
16
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Create a requirements.txt file:
Flask
Create a Dockerfile:
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
17
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1
environment:
- discovery.type=single-node
ports:
- "9200:9200"
logstash:
image: docker.elastic.co/logstash/logstash:7.10.1
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:7.10.1
ports:
- "5601:5601"
depends_on:
18
- elasticsearch
scrape_configs:
- job_name: 'docker-metrics'
static_configs:
- targets: ['web:5000']
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "docker-logs"
}
19
}
Final Outcome
20
7. Secure Docker Deployment with Traefik and Let's
Encrypt
Goal: Deploy a secure, production-ready Docker application with Traefik
(reverse proxy), SSL (Let's Encrypt), and authentication.
Tech Stack:
Docker & Docker Compose
Traefik (Reverse Proxy & Load Balancer)
Let's Encrypt (SSL Certificates)
Basic Authentication
Implementation Steps:
Step 1: Set Up a Sample Web Application
Create a simple Flask or Node.js app (app.py for Flask):
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Secure Docker Deployment with Traefik!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Create a requirements.txt file:
Flask
Create a Dockerfile:
21
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
exposedByDefault: false
certificatesResolvers:
myresolver:
acme:
22
email: [email protected]
storage: acme.json
httpChallenge:
entryPoint: web
NOTE: Change [email protected] to your actual email to request an SSL
certificate.
networks:
webnet:
IMPORTANT: Replace yourdomain.com with your actual domain.
Generate a Basic Auth Password using:
echo $(htpasswd -nb admin mypassword) | sed -e s/\\$/\\$\\$/g
Then, replace the hashed password in the
traefik.http.middlewares.auth.basicauth.users label.
24
1. Open https://yourdomain.com.
2. Check the SSL certificate (issued by Let's Encrypt).
3. A login prompt should appear (Basic Auth).
Final Outcome
25
8. Scalable Microservices Architecture with Docker
and Kubernetes
Goal: Deploy a microservices-based architecture using Docker, Kubernetes,
and an API Gateway for efficient scaling and management.
Tech Stack:
Docker (Containerization)
Kubernetes (Orchestration)
NGINX or Traefik (API Gateway)
Flask/Node.js (Microservices)
MongoDB/PostgreSQL (Database)
Implementation Steps:
Step 1: Define the Microservices
Let's create three microservices:
1⃣ User Service (Handles user authentication)
2⃣ Product Service (Manages product information)
3⃣ Order Service (Processes orders)
Example User Service (user_service/app.py):
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/users", methods=["GET"])
def get_users():
return jsonify({"users": ["Alice", "Bob", "Charlie"]})
if __name__ == "__main__":
26
app.run(host="0.0.0.0", port=5001)
Create a requirements.txt:
Flask
Create a Dockerfile for the service:
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Repeat this process for Product and Order services, changing the API endpoints
accordingly.
29
port:
number: 80
30
Final Outcome
31
9. Continuous Integration & Deployment (CI/CD) for
Dockerized Applications
Goal: Automate the building, testing, and deployment of a Dockerized
application using GitHub Actions & Jenkins with Docker and Kubernetes.
Tech Stack:
Docker (Containerization)
GitHub Actions / Jenkins (CI/CD Automation)
Kubernetes / Docker Compose (Deployment)
Flask/Node.js (Sample Application)
Implementation Steps:
Step 1: Create a Sample Web Application
Let’s use a simple Flask app (app.py):
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Automated CI/CD with Docker!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Create a requirements.txt:
Flask
Create a Dockerfile:
32
sql
CopyEdit
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
33
uses: docker/setup-buildx-action@v2
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to Server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
docker pull myusername/myapp:latest
docker stop myapp || true
docker rm myapp || true
docker run -d -p 80:5000 --name myapp myusername/myapp:latest
34
NOTE: Replace myusername/myapp with your Docker Hub repo name.
Store your Docker Hub credentials & server SSH key as GitHub Secrets.
35
sh '''
ssh user@server "docker pull myusername/myapp:latest && \
docker stop myapp || true && \
docker rm myapp || true && \
docker run -d -p 80:5000 --name myapp myusername/myapp:latest"
'''
}
}
}
}
Add your Docker Hub credentials in Jenkins under Manage Credentials.
36
app: myapp
spec:
containers:
- name: myapp
image: myusername/myapp:latest
ports:
- containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 5000
type: LoadBalancer
Apply the deployment:
bash
CopyEdit
kubectl apply -f myapp-deployment.yaml
37
1. Push code to GitHub → Triggers CI/CD workflow.
2. GitHub Actions/Jenkins builds and deploys the app.
3. Visit http://your-server-ip to see the deployed app.
Final Outcome
38
10. Multi-Stage Docker Build for Optimized Production
Deployment
Goal: Use multi-stage builds to create a lightweight, optimized Docker image
for a production-ready application.
Tech Stack:
Docker (Multi-Stage Builds)
Nginx (Reverse Proxy)
Flask/Node.js (Sample Application)
Implementation Steps:
Step 1: Create a Sample Web Application
Let's use a simple Flask app (app.py):
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Optimized Docker Multi-Stage Build!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Create a requirements.txt:
nginx
CopyEdit
Flask
39
gunicorn
40
server {
listen 80;
location / {
proxy_pass http://web:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
services:
web:
build: .
container_name: web_app
ports:
- "5000:5000"
nginx:
image: nginx:latest
container_name: nginx_proxy
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
41
depends_on:
- web
Final Outcome
42
Conclusion
Mastering Docker requires a hands-on approach, and the 10 projects outlined
in this document provide a structured learning path that takes you from basic
containerization to advanced deployment and orchestration. By working
through these projects, you have gained experience with:
43