docker.recipes

FastAPI Production Stack

advanced

Production FastAPI with Uvicorn, Celery, PostgreSQL, and Redis.

Overview

FastAPI is a modern, high-performance web framework for building APIs with Python 3.7+ that leverages standard Python type hints for automatic API documentation and data validation. Created by Sebastian Ramirez in 2018, FastAPI combines the speed of NodeJS and Go with Python's ease of use, achieving performance comparable to NodeJS thanks to Starlette and Pydantic under the hood. It automatically generates OpenAPI (Swagger) documentation and supports async/await natively, making it ideal for I/O-bound applications that need to handle thousands of concurrent connections. This production stack combines FastAPI with Uvicorn's ASGI server for async request handling, Celery for distributed task processing, PostgreSQL for ACID-compliant data persistence, Redis for caching and message brokering, and NGINX for reverse proxying and load balancing. The architecture separates concerns effectively: FastAPI handles API requests asynchronously, Celery workers process background jobs like email sending or data processing, PostgreSQL manages complex relational data with full transaction support, Redis provides sub-millisecond caching and serves as Celery's message broker, while NGINX terminates SSL and distributes traffic across multiple FastAPI workers. This stack is perfect for startups building scalable SaaS platforms, enterprises migrating from Django/Flask to async Python, and teams developing data-intensive applications that need background processing capabilities. The combination delivers production-grade performance with FastAPI's 10,000+ requests per second capability, PostgreSQL's enterprise reliability, and Celery's proven distributed task management, making it suitable for applications ranging from financial APIs to machine learning pipelines that require both real-time responses and heavy background computation.

Key Features

  • Automatic OpenAPI/Swagger documentation generation from Python type hints with interactive API testing interface
  • Async/await native support with Uvicorn ASGI server for handling 10,000+ concurrent connections
  • Celery distributed task queue with Redis broker for background job processing and scheduled tasks
  • PostgreSQL with asyncpg driver for non-blocking database operations and ACID transaction support
  • Redis-powered caching layer with sub-millisecond response times for frequently accessed data
  • NGINX reverse proxy with HTTP/2 support and load balancing across multiple FastAPI workers
  • Flower web interface for real-time Celery task monitoring and worker management
  • Separate Celery Beat scheduler for cron-like periodic task execution

Common Use Cases

  • 1SaaS platforms requiring user authentication, subscription management, and background email/notification processing
  • 2Financial APIs handling real-time trading data with async PostgreSQL operations and Redis caching for market data
  • 3E-commerce backends processing orders synchronously while handling inventory updates and payment processing asynchronously
  • 4Machine learning platforms serving model predictions via FastAPI while training models in background Celery tasks
  • 5IoT data collection systems ingesting sensor data through FastAPI endpoints and processing analytics in Celery workers
  • 6Content management systems with async file uploads, image processing workflows, and PostgreSQL full-text search
  • 7Multi-tenant applications requiring database-per-tenant isolation with Redis session management and background data synchronization

Prerequisites

  • Minimum 2GB RAM for PostgreSQL database operations and Celery worker processes
  • Docker Engine 20.10+ with Docker Compose V2 for proper async networking and health checks
  • Available ports 80, 443 (NGINX), and 5555 (Flower) on the host system
  • Understanding of Python async/await patterns and SQLAlchemy async sessions
  • Familiarity with Celery task decorators and Redis data structure operations
  • SSL certificate files if enabling HTTPS termination in NGINX configuration

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 postgres:
3 image: postgres:15-alpine
4 environment:
5 - POSTGRES_USER=fastapi
6 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
7 - POSTGRES_DB=fastapi_app
8 volumes:
9 - postgres_data:/var/lib/postgresql/data
10 networks:
11 - fastapi_net
12
13 redis:
14 image: redis:7-alpine
15 volumes:
16 - redis_data:/data
17 networks:
18 - fastapi_net
19
20 fastapi:
21 build:
22 context: .
23 dockerfile: Dockerfile
24 command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
25 environment:
26 - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
27 - REDIS_URL=redis://redis:6379/0
28 - SECRET_KEY=${SECRET_KEY}
29 depends_on:
30 - postgres
31 - redis
32 networks:
33 - fastapi_net
34
35 celery-worker:
36 build:
37 context: .
38 dockerfile: Dockerfile
39 command: celery -A app.worker worker -l info
40 environment:
41 - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
42 - REDIS_URL=redis://redis:6379/0
43 - SECRET_KEY=${SECRET_KEY}
44 depends_on:
45 - postgres
46 - redis
47 networks:
48 - fastapi_net
49
50 celery-beat:
51 build:
52 context: .
53 dockerfile: Dockerfile
54 command: celery -A app.worker beat -l info
55 environment:
56 - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
57 - REDIS_URL=redis://redis:6379/0
58 - SECRET_KEY=${SECRET_KEY}
59 depends_on:
60 - postgres
61 - redis
62 networks:
63 - fastapi_net
64
65 nginx:
66 image: nginx:alpine
67 ports:
68 - "80:80"
69 - "443:443"
70 volumes:
71 - ./nginx.conf:/etc/nginx/nginx.conf:ro
72 depends_on:
73 - fastapi
74 networks:
75 - fastapi_net
76
77 flower:
78 build:
79 context: .
80 dockerfile: Dockerfile
81 command: celery -A app.worker flower --port=5555
82 ports:
83 - "5555:5555"
84 environment:
85 - REDIS_URL=redis://redis:6379/0
86 depends_on:
87 - celery-worker
88 networks:
89 - fastapi_net
90
91volumes:
92 postgres_data:
93 redis_data:
94
95networks:
96 fastapi_net:

.env Template

.env
1# FastAPI Production
2POSTGRES_PASSWORD=secure_postgres_password
3SECRET_KEY=your_very_long_secret_key_here
4
5# FastAPI at http://localhost
6# API docs at http://localhost/docs
7# Flower at http://localhost:5555

Usage Notes

  1. 1FastAPI at http://localhost
  2. 2Swagger docs at http://localhost/docs
  3. 3ReDoc at http://localhost/redoc
  4. 4Flower at http://localhost:5555
  5. 5Async PostgreSQL with asyncpg

Individual Services(7 services)

Copy individual services to mix and match with your existing compose files.

postgres
postgres:
  image: postgres:15-alpine
  environment:
    - POSTGRES_USER=fastapi
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    - POSTGRES_DB=fastapi_app
  volumes:
    - postgres_data:/var/lib/postgresql/data
  networks:
    - fastapi_net
redis
redis:
  image: redis:7-alpine
  volumes:
    - redis_data:/data
  networks:
    - fastapi_net
fastapi
fastapi:
  build:
    context: .
    dockerfile: Dockerfile
  command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
  environment:
    - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
    - REDIS_URL=redis://redis:6379/0
    - SECRET_KEY=${SECRET_KEY}
  depends_on:
    - postgres
    - redis
  networks:
    - fastapi_net
celery-worker
celery-worker:
  build:
    context: .
    dockerfile: Dockerfile
  command: celery -A app.worker worker -l info
  environment:
    - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
    - REDIS_URL=redis://redis:6379/0
    - SECRET_KEY=${SECRET_KEY}
  depends_on:
    - postgres
    - redis
  networks:
    - fastapi_net
celery-beat
celery-beat:
  build:
    context: .
    dockerfile: Dockerfile
  command: celery -A app.worker beat -l info
  environment:
    - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
    - REDIS_URL=redis://redis:6379/0
    - SECRET_KEY=${SECRET_KEY}
  depends_on:
    - postgres
    - redis
  networks:
    - fastapi_net
nginx
nginx:
  image: nginx:alpine
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf:ro
  depends_on:
    - fastapi
  networks:
    - fastapi_net
flower
flower:
  build:
    context: .
    dockerfile: Dockerfile
  command: celery -A app.worker flower --port=5555
  ports:
    - "5555:5555"
  environment:
    - REDIS_URL=redis://redis:6379/0
  depends_on:
    - celery-worker
  networks:
    - fastapi_net

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 postgres:
5 image: postgres:15-alpine
6 environment:
7 - POSTGRES_USER=fastapi
8 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
9 - POSTGRES_DB=fastapi_app
10 volumes:
11 - postgres_data:/var/lib/postgresql/data
12 networks:
13 - fastapi_net
14
15 redis:
16 image: redis:7-alpine
17 volumes:
18 - redis_data:/data
19 networks:
20 - fastapi_net
21
22 fastapi:
23 build:
24 context: .
25 dockerfile: Dockerfile
26 command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
27 environment:
28 - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
29 - REDIS_URL=redis://redis:6379/0
30 - SECRET_KEY=${SECRET_KEY}
31 depends_on:
32 - postgres
33 - redis
34 networks:
35 - fastapi_net
36
37 celery-worker:
38 build:
39 context: .
40 dockerfile: Dockerfile
41 command: celery -A app.worker worker -l info
42 environment:
43 - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
44 - REDIS_URL=redis://redis:6379/0
45 - SECRET_KEY=${SECRET_KEY}
46 depends_on:
47 - postgres
48 - redis
49 networks:
50 - fastapi_net
51
52 celery-beat:
53 build:
54 context: .
55 dockerfile: Dockerfile
56 command: celery -A app.worker beat -l info
57 environment:
58 - DATABASE_URL=postgresql+asyncpg://fastapi:${POSTGRES_PASSWORD}@postgres:5432/fastapi_app
59 - REDIS_URL=redis://redis:6379/0
60 - SECRET_KEY=${SECRET_KEY}
61 depends_on:
62 - postgres
63 - redis
64 networks:
65 - fastapi_net
66
67 nginx:
68 image: nginx:alpine
69 ports:
70 - "80:80"
71 - "443:443"
72 volumes:
73 - ./nginx.conf:/etc/nginx/nginx.conf:ro
74 depends_on:
75 - fastapi
76 networks:
77 - fastapi_net
78
79 flower:
80 build:
81 context: .
82 dockerfile: Dockerfile
83 command: celery -A app.worker flower --port=5555
84 ports:
85 - "5555:5555"
86 environment:
87 - REDIS_URL=redis://redis:6379/0
88 depends_on:
89 - celery-worker
90 networks:
91 - fastapi_net
92
93volumes:
94 postgres_data:
95 redis_data:
96
97networks:
98 fastapi_net:
99EOF
100
101# 2. Create the .env file
102cat > .env << 'EOF'
103# FastAPI Production
104POSTGRES_PASSWORD=secure_postgres_password
105SECRET_KEY=your_very_long_secret_key_here
106
107# FastAPI at http://localhost
108# API docs at http://localhost/docs
109# Flower at http://localhost:5555
110EOF
111
112# 3. Start the services
113docker compose up -d
114
115# 4. View logs
116docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/fastapi-production/run | bash

Troubleshooting

  • asyncpg.exceptions.InvalidCatalogNameError: Ensure PostgreSQL container starts before FastAPI by adding health checks or startup delays
  • Celery workers not discovering tasks: Verify PYTHONPATH includes app directory and task modules are properly imported in worker.py
  • FastAPI 422 validation errors: Check Pydantic model field types match incoming JSON data structure and required fields
  • Redis connection refused in Celery: Confirm Redis container is running and REDIS_URL environment variable uses correct host 'redis' not 'localhost',
  • NGINX 502 Bad Gateway: FastAPI container may not be ready; add upstream health checks or increase proxy timeouts in nginx.conf
  • PostgreSQL connection pool exhaustion: Increase SQLAlchemy pool_size and max_overflow settings or implement connection pooling with pgbouncer

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space