In today's fast-paced software development world, DevOps practices are essential for streamlining workflows, ensuring reliable deployments, and monitoring applications effectively. This tutorial walks you through a hands-on DevOps project using Flask as the web framework, Pytest and Playwright for testing, Docker for containerization, GitHub Actions and Jenkins for CI/CD, and Prometheus with Grafana for monitoring. Whether you're a beginner or an experienced engineer, this guide will help you build, test, deploy, and monitor a simple Flask app.
By the end, you'll have a production-ready setup that demonstrates key DevOps principles like automation, containerization, and observability. Let's dive in!
Project Overview: What We're Building
This DevOps project creates a basic Flask web application that serves a simple HTML template. We integrate testing, containerization, CI/CD pipelines, and monitoring to create a robust ecosystem. Key tools include:
- Flask: For the backend web app.
- Pytest & Playwright: For unit and end-to-end (E2E) testing.
- Docker: For building and orchestrating containers.
- GitHub Actions & Jenkins: For automated CI/CD.
- Prometheus & Grafana: For metrics collection and visualization.
The full source code is available on GitHub. Keywords: DevOps tutorial, Flask Docker CI/CD, Prometheus Grafana monitoring.
Step 1: Setting Up the Flask Application
Start by creating a simple Flask app. Install dependencies like flask and prometheus_flask_exporter for metrics exposure.
Here's the core app.py code:
from flask import Flask, render_template
from prometheus_flask_exporter import PrometheusMetrics
app = Flask(__name__)
metrics = PrometheusMetrics(app)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
This app renders an index.html from the templates folder and exposes metrics at /metrics. The static folder holds CSS styles for a polished UI. Run it locally with python app.py and access at http://localhost:5000.
For SEO: Flask web app tutorial, Python DevOps project.
Step 2: Implementing Tests with Pytest and Playwright
Testing is crucial in DevOps. We use Pytest for backend unit tests and Playwright for E2E browser automation.
Install libraries: pip install pytest playwright.
-
Backend Tests (
tests/test_app.py): Verifies routes and responses.
Example test:
from app import app
def test_home():
client = app.test_client()
response = client.get('/')
assert response.status_code == 200
-
E2E Tests (
tests/test_e2e.py): Simulates browser interactions.
Run the app first, then pytest. All 4 tests (2 backend, 2 E2E) should pass. Note: Keep the app running on localhost:5000 for Playwright to test the UI.
This ensures code quality before deployment. Keywords: Pytest Playwright tutorial, automated testing DevOps.
Step 3: Containerizing with Docker
Docker makes deployments consistent. We use a multistage Dockerfile for efficiency:
# Builder stage
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Runtime stage
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app .
EXPOSE 5000
CMD ["python", "app.py"]
Build and push: docker build -t yourusername/flask-app:latest . and docker push yourusername/flask-app:latest.
For orchestration, docker-compose.yml spins up the full stack:
version: '3'
services:
app:
build: .
ports:
- "5000:5000"
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
jenkins:
image: jenkins/jenkins:lts
ports:
- "8080:8080"
- "50000:50000"
volumes:
- jenkins_home:/var/jenkins_home
volumes:
jenkins_home:
Run with docker-compose up. Access services at:
- Flask:
http://localhost:5000 - Prometheus:
http://localhost:9090 - Grafana:
http://localhost:3000 - Jenkins:
http://localhost:8080
The prometheus.yml configures scraping:
scrape_configs:
- job_name: 'flask'
scrape_interval: 15s
metrics_path: '/metrics'
static_configs:
- targets: ['app:5000']
Keywords: Docker multistage build, Docker Compose DevOps.
Step 4: CI/CD with GitHub Actions and Jenkins
Automation is the heart of DevOps.
-
GitHub Actions (
.github/workflows/ci.yml): Triggers on push/PR to main. Tests, builds, and pushes Docker image if tests pass.
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with: { python-version: '3.12' }
- run: pip install -r requirements.txt
- run: pytest
- name: Build and Push Docker
if: success()
uses: docker/build-push-action@v2
with:
push: true
tags: yourusername/flask-app:latest
-
Jenkins (
Jenkinsfile): Pipeline for build, test, and deploy.
pipeline {
agent { docker { image 'python:3.12' } }
stages {
stage('Build') { steps { sh 'pip install -r requirements.txt' } }
stage('Test') { steps { sh 'pytest' } }
stage('Deploy') {
steps {
withCredentials([usernamePassword(credentialsId: 'dockerhub', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
sh 'docker build -t $USER/flask-app:latest .'
sh 'echo $PASS | docker login -u $USER --password-stdin'
sh 'docker push $USER/flask-app:latest'
}
}
}
}
}
Setup Jenkins: Install Docker, Docker Pipeline, and Git plugins. Restart at http://localhost:8080/restart. Create a pipeline with your GitHub repo.
Keywords: Jenkins CI/CD pipeline, GitHub Actions Docker push.
Step 5: Monitoring with Prometheus and Grafana
Expose metrics via prometheus_flask_exporter. In Grafana, add Prometheus as data source (http://prometheus:9090), create dashboards for app metrics like requests and response times.
This setup provides real-time insights. Keywords: Prometheus Grafana tutorial, Flask monitoring DevOps.
Conclusion: Why This DevOps Project Matters
This project showcases a full DevOps lifecycle: from coding and testing to deployment and monitoring. It's scalable, automated, and observable—perfect for modern apps. Fork the repo, experiment, and level up your skills!
For more repos, follow me on GitHub. Share your thoughts in the comments!
Top comments (0)