Files
devopsexam/README.md
2026-05-13 16:38:46 +02:00

4.6 KiB

Flask DevOps Reference Application

This repository contains a modified Flask application used as a reference implementation for a DevOps setup for Auby & Brinch Finance.

The project demonstrates how a small development team can move from manual releases to a more controlled workflow using GitLab CI/CD, Docker, automated testing, container registry and Kubernetes deployments to separate staging and production environments.

Project Context

Auby & Brinch Finance currently has a small software team with limited DevOps experience. Their internal web application is important for daily business operations, and the company plans to grow the development team.

The purpose of this repository is to demonstrate a suggested technical setup that supports:

  • Automated testing with coverage
  • Containerized application builds
  • GitLab Container Registry
  • Automated deployment to staging
  • Manual approval before production deployment
  • Separate Kubernetes namespaces for staging and production
  • SQLite for local development
  • PostgreSQL for staging and production
  • Gunicorn for containerized runtime

Repository Structure

.
├── app.py                  # Flask application routes
├── database.py             # SQLite/PostgreSQL database access
├── config.py               # Flask configuration
├── requirements.txt        # Python dependencies
├── Dockerfile              # Container image definition
├── compose.yml             # Local Docker Compose setup
├── .gitlab-ci.yml          # GitLab CI/CD pipeline
├── .dockerignore           # Files excluded from Docker build context
├── tests/                  # Pytest test suite
├── manifests/
│   ├── stage/              # Kubernetes manifests for staging
│   └── prod/               # Kubernetes manifests for production
├── templates/              # Flask HTML templates
├── static/                 # Static assets
├── image_pool/             # Uploaded/example images
└── database_file/          # Local SQLite databases

Local Development

The application uses SQLite by default when DATABASE_URL is not set.

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python app.py

The application starts on:

http://localhost:5000

Example login:

Username: admin
Password: admin

Running Tests

Run the automated test suite:

PYTHONPATH=. pytest -q

Run tests with coverage reporting:

PYTHONPATH=. pytest --cov=. --cov-report=term-missing

At the time of writing, the test suite covers basic routing, authentication behavior and selected authenticated actions, reaching approximately 69% coverage.

Docker

Build the application image locally:

docker build -t flask-devops-app .

Run the image locally:

docker run --rm -p 5000:5000 flask-devops-app

The container uses Gunicorn:

gunicorn -b 0.0.0.0:5000 app:app

Docker Compose

A local Compose setup is included:

docker compose up --build

The Compose file starts:

  • Flask application
  • PostgreSQL database

When DATABASE_URL is set, the application uses PostgreSQL. Otherwise it uses the local SQLite database files.

CI/CD Pipeline

The GitLab pipeline is defined in .gitlab-ci.yml.

Pipeline stages:

test -> build -> deploy

The pipeline:

  1. Runs pytest with coverage.
  2. Builds a Docker image with Kaniko.
  3. Pushes the image to GitLab Container Registry.
  4. Deploys automatically to staging when changes are merged to main.
  5. Provides a manual production deployment job.

Kubernetes Deployment

Kubernetes manifests are stored in:

manifests/stage/
manifests/prod/

The setup uses separate namespaces:

stage
prod

Each environment contains manifests for:

  • Flask deployment
  • Flask service
  • PostgreSQL deployment
  • PostgreSQL service
  • PostgreSQL secret

The Flask application receives a DATABASE_URL environment variable in staging and production.

GitLab Variables

The pipeline expects the following variables:

KUBECONFIGCONTENT
CI_REGISTRY
CI_REGISTRY_USER
CI_REGISTRY_PASSWORD
CI_REGISTRY_IMAGE
CI_COMMIT_SHORT_SHA

Most CI_* variables are provided by GitLab automatically. KUBECONFIGCONTENT must be configured in GitLab CI/CD variables and should be protected.

Operational Notes

This reference setup demonstrates the delivery workflow. In a production rollout, PostgreSQL should use persistent storage, secrets should be managed outside the repository, and Kubernetes health checks/resource limits should be added.