A production-ready FastAPI backend template with Docker, MySQL, Redis, MinIO (S3-compatible storage), and authentication built-in. This template provides a solid foundation for building scalable web applications with modern Python technologies.
- Features
- Architecture Overview
- Prerequisites
- Quick Start
- Project Structure
- Configuration
- Services
- Authentication & Authorization
- Database Management
- API Documentation
- Development Guide
- Production Deployment
- Troubleshooting
- FastAPI - Modern, fast web framework for building APIs
- Docker & Docker Compose - Containerized development and deployment
- MySQL 8.3 - Relational database with Adminer GUI
- Redis 7.0 - In-memory data store for caching and sessions
- MinIO - S3-compatible object storage for file uploads
- Alembic - Database migration tool
- JWT Authentication - OAuth2 with Bearer tokens
- Multi-level Authorization - User, Admin, and Super Admin roles
- Auto-generated API Documentation - Swagger UI, ReDoc, and Stoplight Elements
- CORS Support - Cross-Origin Resource Sharing enabled
- Environment-based Configuration - Easy configuration management
- Hot Reload - Development server with automatic code reloading
The template uses a microservices architecture with the following components:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ │ │ │ │ │
│ FastAPI App │─── ▶│ MySQL │ │ Redis │
│ (Port 8000) │ │ (Port 3306) │ │ (Port 6379) │
│ │ │ │ │ │
└────────┬────────┘ └─────────────────┘ └─────────────────┘
│ ┌─────────────────┐ ┌─────────────────┐
│ │ │ │ │
└─────────────▶│ MinIO │ │ Adminer │
│ (Ports 9000/1) │ │ (Port 8001) │
│ │ │ │
└─────────────────┘ └─────────────────┘
- Docker Engine 20.10+
- Docker Compose 2.0+
- Git
- Python 3.11+ (for local development)
-
Clone the repository
git clone <repository-url> cd FastAPI-template
-
Set up environment variables
cp example.env .env # Edit .env file with your configurations if needed
-
Start all services
docker-compose up -d
-
Initialize the database
- Visit http://localhost:8000/db/renewDB to create database tables
- This endpoint requires Super Admin authentication (X-SUPER-ADMIN-TOKEN: admin.root)
-
Access the services
- FastAPI Application: http://localhost:8000
- API Documentation: http://localhost:8000/docs
- Database Admin (Adminer): http://localhost:8001
- MinIO Console: http://localhost:9001 (admin/admin1234)
FastAPI-template/
├── alembic/ # Database migration files
│ ├── versions/ # Migration version files
│ ├── env.py # Alembic environment config
│ └── script.py.mako # Migration template
├── src/ # Application source code
│ ├── crud/ # Database CRUD operations
│ │ └── user.py # User-related CRUD operations
│ ├── database/ # Database configuration
│ │ ├── database.py # Database connection setup
│ │ ├── models.py # SQLAlchemy models
│ │ └── utils.py # Database utilities
│ ├── dependencies/ # FastAPI dependencies
│ │ ├── auth.py # Authentication dependencies
│ │ └── basic.py # Basic dependencies
│ ├── routers/ # API route handlers
│ │ ├── db/ # Database management routes
│ │ ├── private/ # Authenticated user routes
│ │ ├── public/ # Public routes
│ │ └── root/ # Admin routes
│ ├── schemas/ # Pydantic models
│ │ ├── base.py # Base schema classes
│ │ └── basic.py # Basic schema models
│ ├── utils/ # Utility functions
│ │ ├── credentials.py # Password & JWT handling
│ │ ├── handler.py # Error handlers
│ │ ├── s3.py # S3/MinIO integration
│ │ └── swagger.py # Custom Swagger UI
│ └── server.py # Main FastAPI application
├── volume/ # Docker volumes (gitignored)
├── docker-compose.yaml # Docker services configuration
├── Dockerfile # Backend container definition
├── requirements.txt # Python dependencies
├── alembic.ini # Alembic configuration
├── example.env # Environment variables template
├── init-minio.sh # MinIO initialization script
└── minio-entrypoint.sh # MinIO startup script
Copy example.env
to .env
and configure:
# Database Configuration
DB_HOST=mysql # MySQL container hostname
DB_USER=admin # Database user
DB_PASS=admin1234 # Database password
DB_PORT=3306 # MySQL port
DB_NAME=template_db # Database name
# AWS S3 Configuration (for production)
AWS_ACCESS_KEY_ID= # AWS access key
AWS_SECRET_ACCESS_KEY= # AWS secret key
AWS_REGION= # AWS region
AWS_S3_BUCKET=template-bucket
AWS_CLOUDFRONT_DOMAIN= # CloudFront distribution domain
# MinIO Configuration (for development)
S3_ENDPOINT_URL=http://minio:9000
S3_PROVIDER=minio # Use 'aws' for production
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=admin1234
MINIO_DNS_URL=http://localhost:9000
# API Keys
ADMIN_API_KEY=admin # Admin API key
SUPER_ADMIN_API_KEY=admin.root # Super Admin API key
The main application service running on port 8000:
- Framework: FastAPI with Uvicorn ASGI server
- Features: Auto-reload, CORS enabled, JWT authentication
- Endpoints: Public, Private (authenticated), Admin, and Database management
Relational database for persistent data storage:
- Version: MySQL 8.3
- Default Database: template_db
- Root Password: root
- User Credentials: admin/admin1234
- Data Persistence: ./volume/mysql_data
In-memory data store for caching and sessions:
- Version: Redis 7.0 Alpine
- Port: 6379 (internal only)
- Data Persistence: ./volume/redis_data
S3-compatible object storage for file uploads:
- API Port: 9000
- Console Port: 9001
- Default Bucket: template-bucket (public read access)
- Credentials: admin/admin1234
- Data Persistence: ./volume/minio_data
Web-based database management tool:
- Port: 8001
- Supported Databases: MySQL, PostgreSQL, SQLite, MS SQL
- Login with: Server: mysql, Username: admin, Password: admin1234
- Login: POST to
/public/auth/login
with username/password - Token: Receive JWT token in response
- Authorization: Include token in Authorization header:
Bearer <token>
-
Public Routes (
/public/*
)- No authentication required
- Login endpoint available here
-
Private Routes (
/private/*
)- Requires valid JWT token
- For authenticated users
-
Admin Routes (
/root/*
)- Requires X-ADMIN-TOKEN header
- Default:
admin
-
Super Admin Routes (
/db/*
)- Requires X-SUPER-ADMIN-TOKEN header
- Default:
admin.root
- Database management operations
Default test user (created via /db/renewDB):
Username: test-username
Password: test-password
The template includes three main models:
-
User - Basic user information
- id (UUID)
- name (unique, 16 chars)
- created_at, updated_at timestamps
-
UserAccount - Authentication credentials
- username (unique, 16 chars)
- password (hashed)
- Linked to User model
-
Blob - File metadata storage
- content_type
- filename
- url (S3/MinIO URL)
- Many-to-many relationship with Users
Initialize/Reset Database:
curl -X POST http://localhost:8000/db/renew \
-H "X-SUPER-ADMIN-TOKEN: admin.root"
Run Alembic Migrations (API):
# Full migration (delete old versions, create revision, and upgrade)
curl -X POST http://localhost:8000/db/alembic \
-H "X-SUPER-ADMIN-TOKEN: admin.root"
# Skip revision generation (only upgrade existing migrations)
curl -X POST "http://localhost:8000/db/alembic?skip_revision=true" \
-H "X-SUPER-ADMIN-TOKEN: admin.root"
# Keep existing version files
curl -X POST "http://localhost:8000/db/alembic?delete_first=false" \
-H "X-SUPER-ADMIN-TOKEN: admin.root"
Create a new migration:
docker exec template-backend alembic revision --autogenerate -m "Description"
Apply migrations:
docker exec template-backend alembic upgrade head
Rollback migration:
docker exec template-backend alembic downgrade -1
The template provides three different API documentation interfaces:
-
Swagger UI (Interactive)
- URL: http://localhost:8000/docs
- Features: Try out endpoints, authentication support
- Custom dark theme included
-
ReDoc (Clean Documentation)
- URL: http://localhost:8000/redoc
- Features: Clean, readable API documentation
-
Stoplight Elements (Modern UI)
- URL: http://localhost:8000/elements
- Features: Modern design, code samples
-
Install Python dependencies locally:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install -r requirements.txt
-
IDE Configuration:
- Set Python interpreter to venv
- Configure PYTHONPATH to include project root
- Enable type checking for better code completion
-
Hot Reload:
- The Docker container runs with
--reload
flag - Changes to Python files automatically restart the server
- The Docker container runs with
1. Create a new model:
# src/database/models.py
class NewModel(Base):
__tablename__ = "new_models"
id = Column(String(36), primary_key=True)
name = Column(String(255))
# Add more fields
2. Create CRUD operations:
# src/crud/new_model.py
from sqlalchemy.orm import Session
from src.database import models
def create_item(db: Session, name: str):
item = models.NewModel(id=str(ulid.new()), name=name)
db.add(item)
db.commit()
return item
3. Create schemas:
# src/schemas/new_model.py
from pydantic import BaseModel
class NewModelCreate(BaseModel):
name: str
class NewModelResponse(BaseModel):
id: str
name: str
class Config:
from_attributes = True
4. Create router:
# src/routers/private/new_model.py
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from src.dependencies.basic import get_db
from src.crud import new_model as crud
from src.schemas import new_model as schemas
router = APIRouter()
@router.post("/", response_model=schemas.NewModelResponse)
def create_item(
item: schemas.NewModelCreate,
db: Session = Depends(get_db)
):
return crud.create_item(db, item.name)
Upload a file:
from src.utils.s3 import s3_client
import ulid
# Upload file
file_key = f"uploads/{ulid.new()}/filename.jpg"
s3_client.upload_file("local_file.jpg", "template-bucket", file_key)
# Get public URL
url = f"http://localhost:9000/template-bucket/{file_key}"
-
Update .env for production:
S3_PROVIDER=aws AWS_ACCESS_KEY_ID=your-key AWS_SECRET_ACCESS_KEY=your-secret AWS_REGION=us-east-1 ADMIN_API_KEY=strong-random-key SUPER_ADMIN_API_KEY=very-strong-random-key
-
Update docker-compose.yaml:
- Remove development volumes
- Change command to use
gunicorn
instead of--reload
- Add health checks
-
Security considerations:
- Use strong, unique passwords
- Enable HTTPS with SSL certificates
- Implement rate limiting
- Add request validation
- Use environment-specific configurations
1. Docker Swarm:
docker stack deploy -c docker-compose.yaml app-stack
2. Kubernetes:
- Convert docker-compose to K8s manifests
- Use ConfigMaps for environment variables
- Set up Ingress for load balancing
3. Cloud Platforms:
- AWS ECS/Fargate
- Google Cloud Run
- Azure Container Instances
Manual backup:
docker exec template-mysql mysqldump -u admin -padmin1234 template_db > backup.sql
Restore backup:
docker exec -i template-mysql mysql -u admin -padmin1234 template_db < backup.sql
1. Container fails to start:
- Check logs:
docker-compose logs backend
- Ensure all ports are available
- Verify environment variables
2. Database connection errors:
- Wait for MySQL to fully initialize
- Check credentials in .env
- Ensure mysql container is running
3. MinIO bucket not accessible:
- Check if initialization script ran
- Verify MinIO credentials
- Ensure bucket policy is applied
4. Authentication failures:
- Verify JWT token is included in headers
- Check token expiration
- Ensure API keys match .env values
# View all logs
docker-compose logs -f
# Check container status
docker-compose ps
# Enter container shell
docker exec -it template-backend bash
# Test database connection
docker exec template-mysql mysql -u admin -padmin1234 -e "SHOW DATABASES;"
# Check Redis connection
docker exec template-redis redis-cli ping
# Stop and remove all containers
docker-compose down
# Remove volumes (WARNING: Deletes all data)
docker-compose down -v
# Clean rebuild
docker-compose build --no-cache
docker-compose up -d
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new features
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.