FastAPI skeleton with JWT auth, PostgreSQL, Redis, Celery, Docker — clone, configure, start building.
An opinionated FastAPI starter for production services — every backend freelance project starts with the same boilerplate. This template eliminates that overhead.
# 1. Clone
git clone https://github.com/pingxin403/fastapi-backend-template.git
cd fastapi-backend-template
# 2. Configure
cp .env.example .env
# Edit .env — change JWT_SECRET at minimum
# 3. Run (PostgreSQL + Redis + app + Celery worker, all in one command)
docker compose up -d
# 4. Run migrations
docker compose exec app alembic upgrade head
# 5. Test
curl -X POST http://localhost:8000/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"securepassword"}'
# Response: { "access_token": "eyJ...", "token_type": "bearer" }FastAPI app
├── /health
├── /auth/register → create user + return JWT
├── /auth/login → validate credentials + return JWT
└── /users/me → fetch current user (requires JWT)
│
├── middleware/auth.py ← JWT validation
├── middleware/rate_limit.py ← token-bucket per-IP
├── routes/auth.py ← register / login
├── routes/users.py ← /me
├── services/auth.py ← hashing, JWT encode/decode
├── services/email.py ← stub → swap with SendGrid/SES
├── tasks/celery_app.py ← async task queue
└── models/user.py ← SQLAlchemy + Alembic
Infrastructure (docker-compose.yml)
├── PostgreSQL 16 ← primary DB
├── Redis 7 ← Celery broker + cache
├── app ← uvicorn (hot-reload in dev)
└── worker ← Celery worker
app/
├── main.py ← FastAPI entrypoint
├── config.py ← Pydantic Settings (.env driven)
├── db.py ← AsyncSQLAlchemy engine + session factory
├── models/
│ ├── base.py ← DeclarativeBase + TimestampMixin
│ └── user.py ← User model (id, email, hashed_password, is_active)
├── routes/
│ ├── auth.py ← POST /auth/register, /auth/login
│ ├── users.py ← GET /users/me
│ └── __init__.py ← router exports
├── middleware/
│ ├── auth.py ← JWT Bearer extraction + validation
│ └── rate_limit.py ← in-memory token-bucket rate limiter
├── services/
│ ├── auth.py ← bcrypt hashing + JWT encode/decode
│ └── email.py ← stub → swap with real provider
└── tasks/
└── celery_app.py ← Celery instance (Redis broker)
tests/
└── test_auth.py ← health + register + login + auth-gate tests
migrations/ ← Alembic (replace `app.models` with your own)
grep -rn "TODO" app/ # shows every customization point| What | Where | What to do |
|---|---|---|
| JWT secret | .env |
Generate openssl rand -hex 32 |
| Database URL | .env / docker-compose.yml |
Point to your PG instance |
| Models | app/models/ |
Add your own tables, update __init__.py |
| Routes | app/routes/ |
Add business endpoints |
app/services/email.py |
Swap stub with SendGrid / SES | |
| Rate limiter | app/middleware/rate_limit.py |
Swap in-memory for Redis-backed for multi-replica |
| Auth provider | app/services/auth.py |
Swap JWT for OAuth/OIDC if needed |
| Celery tasks | app/tasks/ |
Add @celery_app.task functions |
After changing models, generate a migration:
docker compose exec app alembic revision --autogenerate -m "your change"
docker compose exec app alembic upgrade head# Requires PostgreSQL + Redis (use docker compose up db redis)
docker compose up -d db redis
pip install -e ".[dev]"
pytest tests/ -vCovers: health endpoint, input validation, auth gates. Add integration tests with a real DB fixture after registering a test user.
- Replace all
# TODOhooks - Change
allow_origins=["*"]to your frontend origin - Swap in-memory rate limiter for Redis-backed
- Set up proper secret management (not
.envin production) - Add health check probes for K8s
- Add structured logging (structlog / python-json-logger)
- Run
alembic upgrade headbefore app start
- LangGraph agent template: langgraph-agent-template — if you need an AI agent instead of a CRUD backend
- CI/CD workflow templates: cicd-platform-showcase
- Observability platform: observability-platform-showcase