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:
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:
- Runs pytest with coverage.
- Builds a Docker image with Kaniko.
- Pushes the image to GitLab Container Registry.
- Deploys automatically to staging when changes are merged to main.
- 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.