A production-ready FastAPI boilerplate designed for rapid project setup — featuring clean architecture, Docker support, CI/CD, logging and INI-based configuration.
- ⚡ FastAPI with Python 3.14 and Granian (ASGI)
- 🐳 Docker & Docker Compose for development and production
- 🔄 CI/CD pipeline with GitHub Actions
- 🗄️ PostgreSQL database with SQLAlchemy
- 🔴 Redis for caching
- 🔒 Nginx reverse proxy with rate limiting
- 📝 Alembic for database migrations
- 🧪 Pytest for testing
- 📊 Logging configured and ready to use
- 🔧 Makefile for convenient development
- 📦 uv for fast installs (Docker & local
make install)
- Docker and Docker Compose
- Python 3.14+ (for local development; Docker images use 3.14)
- uv (optional; used by Dockerfiles and
make install) - Make (optional)
- Clone the repository:
git clone https://github.com/Reei-dp/fastapi-template.git
cd fastapi-template- Create
config.inifile from example:
cp config.ini.example config.ini- Edit
config.inifile according to your needs
make dev
# or
docker compose -f docker/docker-compose.dev.yml up --buildpython -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
uv pip install -r requirements.txt
python src/main.py
# or
granian --interface asgi src.main:app --reloadApplication will be available at: http://localhost:8000
API documentation:
- Swagger UI: http://localhost:8000/api/docs (protected)
- OpenAPI JSON: http://localhost:8000/api/openapi.json
From the repository root, with config.ini present (non-empty Redis PASSWORD for production compose — see config.ini.example). Inside Docker, set [POSTGRES] IP to postgres and [REDIS] HOST to redis so the app reaches the compose services.
make up
# or
./start.sh -dThis runs docker/sync_compose_from_config.sh and then docker compose up --build from the docker/ directory.
fastapi-template/
├── .github/
│ └── workflows/
│ └── develop.yaml # CI/CD pipeline
├── src/ # Source code
│ ├── main.py # FastAPI application entry point
│ ├── config.py # Configuration loader (INI files)
│ ├── dependencies.py # Global dependencies
│ ├── schemas.py # Shared Pydantic schemas
│ ├── configuration/
│ │ └── app.py # FastAPI app initialization
│ ├── middlewares/ # HTTP middlewares
│ │ ├── __init__.py
│ │ └── database.py # Database session middleware
│ ├── routers/ # API routers
│ │ ├── __init__.py # Router registration
│ │ └── root/ # Root endpoints
│ │ ├── router.py # Route definitions
│ │ ├── actions.py # Business logic
│ │ ├── dal.py # Data access layer
│ │ ├── models.py # Database models
│ │ └── schemas.py # Request/response schemas
│ ├── database/ # Database configuration
│ │ ├── core.py # Database engine and sessions
│ │ ├── base.py # Base model class
│ │ ├── dependencies.py # Database dependencies
│ │ ├── logging.py # Session tracking
│ │ └── alembic/ # Database migrations
│ ├── redis_client/ # Redis operations
│ │ └── redis.py # Redis controller with caching methods
│ ├── services/ # External service integrations
│ └── misc/ # Utilities
│ ├── security.py # Security utilities
│ └── timezone.py # Timezone utilities
├── docker/
│ ├── Dockerfile # Production image
│ ├── Dockerfile.dev # Development image (hot-reload)
│ ├── docker-compose.yml # App, Postgres, Redis
│ ├── docker-compose.dev.yml # Dev stack (app + Postgres + Redis)
│ ├── entrypoint.sh # Migrations + app in production
│ ├── sync_compose_from_config.sh # docker/.env from config.ini
│ └── nginx/
│ └── nginx.conf # Optional Nginx (not wired in compose by default)
├── config.ini.example # Configuration template
├── alembic.ini.example # Alembic configuration template
├── requirements.txt # Python dependencies
├── Makefile # Build commands
├── start.sh # Startup script
└── README.md # This file
make help # Show all available commands
make install # Install dependencies
make dev # Start development environment
make build # Build production Docker image
make up # Start production environment
make down # Stop all containers
make logs # Show logs
make clean # Remove containers and volumes
make test # Run tests
make lint # Run linter
make format # Format code
make migrate # Apply migrations
make migrate-create # Create new migrationWorkflow .github/workflows/develop.yaml (on pull requests to main):
- Writes
config.iniandalembic.inifrom secrets - Copies the repository tree to the server over
scp - Runs
./start.sh -don the server (writesdocker/.envfromconfig.ini, thendocker compose up --build -d)
PROD_SSH_PRIVATE_KEY— SSH private key for the serverPROD_SSH_HOST— Server hostname or IPPROD_SSH_USER— SSH userPROD_CONFIG_INI— Full contents of productionconfig.ini(useecho -ein GitHub Actions, so use\nfor newlines if needed)PROD_ALEMBIC_INI— Full contents of productionalembic.ini
Edit env.REMOTE_PATH in the workflow file so it matches the deploy directory on the server (default: /opt/apps/fastapi-template).
Application uses INI files for configuration (see config.ini.example):
[POSTGRES]
# PostgreSQL database configuration
DATABASE = postgresql
DRIVER = asyncpg
DATABASE_NAME = your_database_name
USERNAME = postgres
PASSWORD = your_password
IP = localhost
PORT = 5432
# Connection pool settings
DATABASE_ENGINE_POOL_TIMEOUT = 30
DATABASE_ENGINE_POOL_RECYCLE = 3600
DATABASE_ENGINE_POOL_SIZE = 5
DATABASE_ENGINE_MAX_OVERFLOW = 10
DATABASE_ENGINE_POOL_PING = true
# Database echo (SQL logging) - set to false in production
DATABASE_ECHO = false
[GRANIAN]
# Granian server configuration
HOST = 0.0.0.0
PORT = 8000
WORKERS = 4
LOOP = uvloop # Event loop: asyncio | uvloop | auto
HTTP = auto # HTTP: auto | http1 | http2
[REDIS]
# Redis cache configuration
HOST = localhost
PORT = 6379
DB = 0
PASSWORD =- Automatic session management per request
- Auto-commit on success, rollback on error
- Session tracking for debugging
- Request ID generation for tracing
- Simple caching interface with
get(),set(),delete(),update() - JSON serialization support with
get_json()andset_json() - TTL (Time To Live) management
- Multiple key deletion support
- Database connectivity check
- Redis connectivity check
- Returns 200 (healthy) or 503 (unhealthy)
- Accessible at
/api/root/health
To run as a systemd service, create /etc/systemd/system/fastapi-app.service (adjust User, paths, and dependencies to match your server):
[Unit]
Description=FastAPI Application Service
After=network.target postgresql.service redis.service
Wants=postgresql.service redis.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/apps/fastapi-app
Environment="PATH=/opt/apps/fastapi-app/venv/bin"
ExecStart=/opt/apps/fastapi-app/venv/bin/python src/main.py
Restart=always
RestartSec=10
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/apps/fastapi-app/logs
StandardOutput=append:/opt/apps/fastapi-app/logs/app.log
StandardError=append:/opt/apps/fastapi-app/logs/error.log
SyslogIdentifier=fastapi-app
[Install]
WantedBy=multi-user.targetThen:
sudo systemctl daemon-reload
sudo systemctl enable fastapi-app
sudo systemctl start fastapi-app# Run all tests
make test
# Run with coverage
pytest --cov=app --cov-report=html
# Run specific test
pytest tests/test_api.py -vmake migrate-create
# or
alembic revision --autogenerate -m "migration description"make migrate
# or
alembic upgrade headmake formatMIT License - see LICENSE file