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

184 lines
4.6 KiB
Markdown

# 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
```text
.
├── 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.
```bash
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:
```text
Username: admin
Password: admin
```
## Running Tests
Run the automated test suite:
```bash
PYTHONPATH=. pytest -q
```
Run tests with coverage reporting:
```bash
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:
```bash
docker build -t flask-devops-app .
```
Run the image locally:
```bash
docker run --rm -p 5000:5000 flask-devops-app
```
The container uses Gunicorn:
```bash
gunicorn -b 0.0.0.0:5000 app:app
```
## Docker Compose
A local Compose setup is included:
```bash
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:
```text
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:
```text
manifests/stage/
manifests/prod/
```
The setup uses separate namespaces:
```text
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:
```text
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.