A production-ready FastAPI template implementing Domain-Driven Design (DDD) and Clean Architecture principles with Dependency Injection, featuring authentication, database migrations, and Docker deployment.
- Clean Architecture: Organized by contexts following DDD principles (NOT strict DDD)
- Dependency Injection: Using
dependency-injectorfor better testability and modularity - Authentication: API Key middleware (global dependency) with public-route decorator
- CLI Commands: Typer-based administrative CLI for user management and more
- Database Management:
- PostgreSQL with async SQLAlchemy
- Alembic for database migrations
- Connection pooling and health checks
- Docker Support: Complete Docker Compose setup for development and production
- Code Quality:
- Ruff for linting and formatting (configured with extensive rule sets)
- Pre-commit hooks
- Type hints targeting Python 3.13
- Structured Logging: Loguru integration with request/response middleware
- Settings Management: Pydantic Settings with environment-based configuration
- Production Ready:
- Multi-stage Docker builds
- Health check endpoints
- Non-root user execution
- Hot reload in development
- Python 3.13+
- uv - Fast Python package installer (used locally and in Docker)
- Docker & Docker Compose (for containerized deployment)
- PostgreSQL 16+ (handled by Docker Compose)
fastapi-template/
βββ src/
β βββ main.py # FastAPI application entry point
β βββ settings.py # Application settings & configuration
β βββ container.py # Dependency injection container
β βββ contexts/ # DDD contexts
β βββ auth/ # Authentication context
β β βββ domain/ # Domain models & repositories
β β βββ application/ # Use cases
β β βββ infrastructure/ # Persistence, HTTP middleware, CLI
β βββ shared/ # Shared kernel
β βββ domain/
β βββ infrastructure/ # Database, cache, logging
βββ migrations/ # Alembic database migrations
βββ scripts/ # Utility scripts (init_db, etc.)
βββ secrets/ # Environment variables (.env)
βββ docker-compose.yaml # Docker services definition
βββ Dockerfile # Multi-stage Docker build
βββ Makefile # Development commands
βββ pyproject.toml # Project dependencies & config
git clone https://github.com/p0llopez/fastapi-template.git
cd fastapi-templateCreate a .env file in the secrets/ directory (used by the app and Docker Compose):
cp secrets/.env.example secrets/.env# Build and start all services
make build && make start
# Or manually:
docker compose up --buildThe API will be available at http://localhost:8080
# Install dependencies with uv
make install
# Or manually:
uv sync
# Run database migrations (requires DATABASE_URL)
make migration-upgrade
# Start the application
uv run uvicorn src.main:app --reloadThe project includes a comprehensive Makefile for common tasks:
make start # Start all services
make stop # Stop all services
make build # Build Docker images
make restart # Restart all services
make logs # Follow application logs
make shell # Open bash in app container
make db-shell # Open psql in database containerIf your environment file lives in secrets/.env, run:
ENV_FILE=secrets/.env make db-shellmake migration-create # Create auto-generated migration
make migration-create-empty # Create empty migration template
make migration-upgrade # Apply all pending migrations
make migration-downgrade # Rollback last migration
make migration-history # Show migration history
make migration-current # Show current migration version
make migration-show # Show current head revision
make migration-sql # Generate SQL for upgrade headmake fmt # Format code with ruff
make lint # Run linter with auto-fix
make test # Run tests with pytest
make all # Run install, format, lint, and test
make clean # Remove __pycache__ and .pyc files# Make sure services are running first
make start
# Show CLI help
make cli
# Run CLI commands (pass args explicitly):
make cli args="auth list-users"
make cli args="auth create-user --username admin --email admin@example.com"
make cli args="auth create-api-key --user-id <uuid>"
make cli args="auth deactivate-api-key --user-id <uuid> --api-key <key>"
# For local development (without Docker):
uv run cli auth create-user --username admin --email admin@example.com
uv run cli auth list-usersThe project is organized into contexts (bounded contexts in DDD terminology):
- Auth Context: Handles authentication, users, and API keys
- Shared Context: Common infrastructure (database, logging, caching)
Each context follows a layered architecture:
- Domain Layer: Business logic, entities, and repository interfaces
- Application Layer: Use cases and business workflows
- Infrastructure Layer: Database models, external services, and implementations
The application uses dependency-injector for managing dependencies:
ApplicationContainer: Root container- Context-specific containers (e.g.,
AuthContainer,SharedContainer) - Providers for repositories, use cases, and services
To add a new feature (e.g., a "Products" context):
-
Create the context structure:
src/contexts/products/ βββ domain/ β βββ aggregates.py # Product entity β βββ repositories.py # Repository interface βββ application/ β βββ use_cases/ # Business logic βββ infrastructure/ βββ container.py # DI container βββ persistence/ # Database models -
Register in the main container (
src/container.py) -
Create database models and migrations
-
Implement use cases and endpoints
The template includes an API Key authentication system and user management:
- User Management: Create and list users via CLI (passwords are bcrypt-hashed)
- API Keys: Generate and validate API keys for authentication
- HTTP: All routes require
X-API-Keyunless explicitly marked public
# Create user (interactive prompt for password)
make cli args="auth create-user"
# List users
make cli args="auth list-users"from src.contexts.auth.application.use_cases import AuthenticateWithApiKeyUseCase
# In your endpoint:
is_valid = await authenticate_use_case.execute(api_key="user-api-key")- Global dependency: all routes require the
X-API-Keyheader. - Public routes: decorate handlers with
@publicto bypass auth. - Health endpoints:
GET /healthis public.GET /health-protectedrequiresX-API-Key.
Note: The auth HTTP endpoints are not exposed yet. Use the CLI for now or add a router under
src/contexts/auth/infrastructure/http/and include it insrc/main.py.
## ποΈ Database
### Migrations
The project uses Alembic for database migrations:
```bash
# Create a new migration after modifying models
make migration-create
# Apply migrations
make migration-upgrade
# Rollback last migration
make migration-downgrade
Run the initialization script to set up the database and apply migrations:
docker compose exec app python -m scripts.init_dbThe Dockerfile uses a multi-stage build for optimized images:
- Base: Python 3.13 slim image
- Builder: Installs dependencies using uv
- Runner: Final image with only runtime dependencies
- Non-root user execution for security
- Compiled bytecode for faster startup
- Health checks for container orchestration
- Volume mounts for hot reload in development
Control build behavior:
# Build with dev dependencies
docker compose build --build-arg INSTALL_DEV=true
# Production build
docker compose build --build-arg INSTALL_DEV=falseConfiguration is managed through src/settings.py using Pydantic Settings:
from src.settings import settings
# Access configuration
if settings.is_production:
# Production-specific code
pass
# Database URL
db_url = settings.database_url
# Feature flags
log_level = settings.log_level- Application:
environment,log_level - Security:
secret_key,allowed_origins - Database:
database_url
Structured logging with Loguru:
- Request/response logging middleware
- Configurable log levels
- JSON formatting for production
- Console formatting for development
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes using conventional commits
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project uses:
- Ruff for linting and formatting
- Pre-commit hooks for automated checks
- Conventional commits with gitmoji
This project is licensed under the MIT License - see the LICENSE file for details.
Pol LΓ³pez Cano
- Email: pol.lopez.cano@gmail.com
- GitHub: @p0llopez
- FastAPI for the excellent web framework
- Astral's uv for blazing-fast package management
- The Python community for amazing tools and libraries
Happy Coding! π