Skip to content

Deploying FastAPI with Docker

🎯 Learning Goals

By the end of this lesson, you will be able to:

  • Write a Dockerfile to containerize your FastAPI app.
  • Understand how to run FastAPI with Gunicorn and Uvicorn workers for production.
  • Build and run Docker images locally, preparing for deployment to cloud platforms.

⚡ Step 1: Create a Dockerfile

📄 Dockerfile

# Use official Python base image
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Install system dependencies (optional, e.g. psycopg2 needs gcc)
RUN apt-get update && apt-get install -y build-essential

# Copy requirements first for caching
COPY requirements.txt .

# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy project files
COPY . .

# Expose port
EXPOSE 8000

# Run Gunicorn with Uvicorn workers
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app", "--bind", "0.0.0.0:8000", "--workers", "4"]

🔍 What’s happening?

  • Base image: python:3.11-slim keeps the image lightweight.
  • WORKDIR: sets /app as the working directory.
  • requirements.txt: installed first to leverage Docker layer caching.
  • COPY . .: copies your project files into the container.
  • EXPOSE 8000: makes port 8000 available.
  • CMD: runs Gunicorn with Uvicorn workers, binding to 0.0.0.0:8000.

⚡ Step 2: requirements.txt

📄 requirements.txt

fastapi
uvicorn[standard]
gunicorn
sqlmodel
psycopg2-binary   # if using PostgreSQL
slowapi           # if using rate limiting

⚡ Step 3: Build and Run the Container

Build the image:

docker build -t fastapi-taskmanager .

Run the container:

docker run -d -p 8000:8000 fastapi-taskmanager

Now your API is available at:

http://localhost:8000

⚡ Step 4: Running with Gunicorn + Uvicorn

Why not just uvicorn main:app?

  • Uvicorn is great for development.
  • Gunicorn manages multiple worker processes, making it more robust in production.
  • The combination (gunicorn -k uvicorn.workers.UvicornWorker) gives you:
    • Multi-worker concurrency
    • Graceful restarts
    • Better monitoring and logging

Example command:

gunicorn -k uvicorn.workers.UvicornWorker main:app --workers 4 --bind 0.0.0.0:8000

⚡ Step 5: Verify Deployment

  • Visit http://localhost:8000/docs to check the interactive API docs.
  • Run a test request:
curl http://localhost:8000/tasks/

🧠 Best Practices

  • Use multi-stage builds to keep images small (build dependencies in one stage, copy only runtime files).
  • Pin dependency versions in requirements.txt for reproducibility.
  • Use environment variables for secrets (e.g. database URL).
  • In production, run behind a reverse proxy (NGINX or Traefik) for TLS termination.

🧪 Practice Challenge

  1. Add a multi-stage Dockerfile that separates build and runtime.
  2. Configure Gunicorn with environment variables for worker count.
  3. Deploy your container to Docker Hub or a cloud provider (AWS ECS, Azure Container Apps, GCP Cloud Run).

🧠 Recap

In this lesson, you:

  • Wrote a Dockerfile to containerize your FastAPI app.
  • Ran FastAPI with Gunicorn + Uvicorn workers for production readiness.
  • Built and ran your container locally, preparing for deployment.