A minimal Flask boilerplate following the MVC pattern — designed as a clean starting point for new Python web applications.
- Application Factory (
create_app()) — safe for testing and multiple configs - Blueprint-based controllers — one file per resource, explicit registration
- Environment-based configuration —
Development,Testing,Productionconfig classes - POST/Redirect/GET form handling — prevents double-submit on refresh
- Jinja2 macro library — shared
render_errorand helpers inlayout/macros.html - Test suite — 96% coverage out of the box with pytest + pytest-cov
- Docker-ready — optimised multi-layer
Dockerfileanddocker-compose.yml
flask-mvc/
├── project/
│ ├── __init__.py # create_app() factory
│ ├── config.py # Dev / Testing / Production config classes
│ ├── controllers/
│ │ └── printer.py # printer Blueprint + form
│ ├── models/
│ │ └── printer.py # Printer model
│ ├── static/css/
│ └── templates/
│ ├── layout/
│ │ ├── layout.html # base template
│ │ └── macros.html # reusable Jinja2 macros
│ └── printer/
├── tests/
│ ├── conftest.py # app / client fixtures
│ └── test_printer.py
├── .env.example # required env vars — copy to .env before running
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── requirements-test.txt
└── runserver.py
- Python 3.14+
- pip
Optional (for Python version management):
brew install asdf
asdf plugin add python
asdf install python 3.14.4# 1. Clone
git clone git@github.com:salimane/flask-mvc.git
cd flask-mvc
# 2. Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate
# 3. Install dependencies
pip install -r requirements-test.txt
# 4. Configure environment
cp .env.example .env
# Open .env and set SECRET_KEY — generate one with:
# python -c "import secrets; print(secrets.token_hex(32))"# Development server (reads PORT from env, default 8080)
source .env && python runserver.py
# Or via Make
make runcp .env.example .env # fill in SECRET_KEY
docker-compose up --buildThe app is served by gunicorn on port 16000 inside the container.
SECRET_KEY=test pytest tests/ -v --cov=project --cov-report=term-missingOr via the helper script (creates an isolated virtualenv automatically):
script/testName Stmts Miss Cover
-----------------------------------------------------
project/__init__.py 15 1 93%
project/config.py 20 1 95%
project/controllers/printer.py 18 0 100%
project/models/printer.py 4 0 100%
-----------------------------------------------------
TOTAL 57 2 96%
All configuration is driven by environment variables. See .env.example for the full list.
| Variable | Required | Default | Description |
|---|---|---|---|
SECRET_KEY |
Yes | — | Flask session / CSRF signing key |
FLASK_ENV |
No | development |
Config profile (development, testing, production) |
PORT |
No | 8080 |
Dev server port |
Generate a secure key:
python -c "import secrets; print(secrets.token_hex(32))"To add a new resource (e.g. user):
- Model —
project/models/user.py - Controller —
project/controllers/user.pywithuser_bp = Blueprint('user', __name__) - Register — add
app.register_blueprint(user_bp)increate_app()(project/__init__.py) - Templates —
project/templates/user/ - Tests —
tests/test_user.py
See .github/copilot-instructions.md for the full development
guide and coding conventions.
Issues and pull requests are welcome. Please keep PRs focused — one concern per PR.
Copyright © 2026 Salimane Adjao Moustapha. Licensed under the MIT License.