Updated README to accurately reflect the repo
This commit is contained in:
177
README.md
177
README.md
@@ -1,60 +1,183 @@
|
|||||||
# flask-example
|
# Flask DevOps Reference Application
|
||||||
|
|
||||||
A minimal web app developed with [Flask](http://flask.pocoo.org/) framework.
|
This repository contains a modified Flask application used as a reference implementation for a DevOps setup for Auby & Brinch Finance.
|
||||||
|
|
||||||
The main purpose is to introduce how to implement the essential elements in web application with Flask, including
|
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.
|
||||||
|
|
||||||
- URL Building
|
## Project Context
|
||||||
|
|
||||||
- Authentication with Sessions
|
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.
|
||||||
|
|
||||||
- Template & Template Inheritance
|
The purpose of this repository is to demonstrate a suggested technical setup that supports:
|
||||||
|
|
||||||
- Error Handling
|
- 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
|
||||||
|
|
||||||
- Integrating with *Bootstrap*
|
## Repository Structure
|
||||||
|
|
||||||
- Interaction with Database (SQLite)
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
- Invoking static resources
|
## Local Development
|
||||||
|
|
||||||
For more basic knowledge of Flask, you can refer to [a tutorial on Tutorialspoint](https://www.tutorialspoint.com/flask/).
|
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
|
||||||
|
```
|
||||||
|
|
||||||
## How to Run
|
The application starts on:
|
||||||
|
|
||||||
- Step 1: Make sure you have Python
|
http://localhost:5000
|
||||||
|
|
||||||
- Step 2: Install the requirements: `pip install -r requirements.txt`
|
Example login:
|
||||||
|
|
||||||
- Step 3: Go to this app's directory and run `python app.py`
|
```text
|
||||||
|
Username: admin
|
||||||
|
Password: admin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
Run the automated test suite:
|
||||||
|
|
||||||
## Details about This Toy App
|
```bash
|
||||||
|
PYTHONPATH=. pytest -q
|
||||||
|
```
|
||||||
|
|
||||||
There are three tabs in this toy app
|
Run tests with coverage reporting:
|
||||||
|
|
||||||
- **Public**: this is a page which can be accessed by anyone, no matter if the user has logged in or not.
|
```bash
|
||||||
|
PYTHONPATH=. pytest --cov=. --cov-report=term-missing
|
||||||
|
```
|
||||||
|
|
||||||
- **Private**: Only logged-in user can access this page. Otherwise the user will get a 401 error page.
|
At the time of writing, the test suite covers basic routing, authentication behavior and selected authenticated actions, reaching approximately 69% coverage.
|
||||||
|
|
||||||
- **Admin Page**: This part is only open to the user who logged in as "Admin". In this tab, the administrator can manage accounts (list, delete, or add).
|
## Docker
|
||||||
|
|
||||||
|
Build the application image locally:
|
||||||
|
|
||||||
A few accounts were set for testing, like ***admin*** (password: admin), ***test*** (password: 123456), etc. You can also delete or add accounts after you log in as ***admin***.
|
```bash
|
||||||
|
docker build -t flask-devops-app .
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the image locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -p 5000:5000 flask-devops-app
|
||||||
|
```
|
||||||
|
|
||||||
## References
|
The container uses Gunicorn:
|
||||||
|
|
||||||
- http://flask.pocoo.org/
|
```bash
|
||||||
|
gunicorn -b 0.0.0.0:5000 app:app
|
||||||
|
```
|
||||||
|
|
||||||
- https://www.tutorialspoint.com/flask/
|
## Docker Compose
|
||||||
|
|
||||||
|
A local Compose setup is included:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
## Credict
|
The Compose file starts:
|
||||||
Image private.jpg: https://commons.wikimedia.org/wiki/File:(315-365)_Locked_(6149414678).jpg
|
|
||||||
|
|
||||||
Image public.jpg: https://commons.wikimedia.org/wiki/File:Drown%3F!_(131380682).jpg
|
- 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.
|
||||||
|
|||||||
Reference in New Issue
Block a user