Skip to main content

Deployment and Docker Commands

Quick-lookup reference for deploying FastAPI apps — Uvicorn for development, Gunicorn with Uvicorn workers for production, Docker Compose for local stacks, and Alembic for database migrations.

Learning Focus

By the end of this reference you can: quickly recall the exact commands for running, building, deploying, and debugging FastAPI applications in development and production environments.

Uvicorn (Development)

# Basic
uvicorn app.main:app --reload

# With options
uvicorn app.main:app \
--host 0.0.0.0 \
--port 8000 \
--reload \
--log-level debug \
--workers 1

# With SSL
uvicorn app.main:app \
--ssl-keyfile ./key.pem \
--ssl-certfile ./cert.pem

Gunicorn (Production)

# With UvicornWorker
gunicorn app.main:app \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8000 \
--timeout 60 \
--graceful-timeout 30 \
--access-logfile - \
--error-logfile -

# With config file
gunicorn app.main:app --config gunicorn.conf.py

# Graceful reload (zero-downtime)
kill -HUP $(cat gunicorn.pid)
# OR
systemctl reload fastapi

Docker Build and Run

# Build
docker build -t myapi:latest .
docker build -t myapi:1.0.0 -f Dockerfile.prod .

# Run
docker run -d \
--name myapi \
-p 8000:8000 \
--env-file .env \
myapi:latest

# Shell into running container
docker exec -it myapi bash

# View logs
docker logs -f myapi --tail=100

# Stop and remove
docker stop myapi && docker rm myapi

Docker Compose

# Start all services
docker compose up -d

# Build and start
docker compose up -d --build

# Start specific service
docker compose up -d app

# View logs
docker compose logs -f
docker compose logs -f app --tail=50

# Run one-off command
docker compose exec app alembic upgrade head
docker compose exec app python -m pytest

# Scale app
docker compose up -d --scale app=3

# Stop all
docker compose down

# Stop and remove volumes
docker compose down -v

Alembic Commands

# Generate migration from model changes
alembic revision --autogenerate -m "description"

# Apply all pending migrations
alembic upgrade head

# Apply one step
alembic upgrade +1

# Roll back one step
alembic downgrade -1

# Roll back to specific revision
alembic downgrade <revision_id>

# Roll back everything
alembic downgrade base

# Show current revision
alembic current

# Show history
alembic history --verbose

# Mark current state without running migrations
alembic stamp head

Health Check and Diagnostics

# Check API health
curl http://localhost:8000/health

# Check OpenAPI docs available
curl -s http://localhost:8000/openapi.json | python -m json.tool | head -20

# Check response time
time curl -s http://localhost:8000/health

# Load test
hey -n 1000 -c 50 http://localhost:8000/health

# Check PostgreSQL connections
psql "${DATABASE_URL}" -c "SELECT count(*) FROM pg_stat_activity;"

# Test WebSocket
wscat -c ws://localhost:8000/ws

Environment and Secrets

# Generate SECRET_KEY
python -c "import secrets; print(secrets.token_hex(32))"

# Generate a UUID
python -c "import uuid; print(uuid.uuid4())"

# Check settings load correctly
python -c "from app.core.config import settings; print(settings.model_dump())"

# Validate .env file
python -c "
from app.core.config import Settings
try:
s = Settings()
print('Settings OK:', s.ENV, s.DATABASE_URL[:20] + '...')
except Exception as e:
print('Settings ERROR:', e)
"

Common Pitfalls

PitfallCause / SymptomFix
App fails to start in DockerDATABASE_URL points to localhost instead of db service nameUse Docker Compose service names: postgresql+asyncpg://...@db:5432/app
Gunicorn workers = 1 on multi-coreNot setting --workers or defaulting to 1Set --workers $(nproc) or a multiple of CPU cores
Alembic head not idempotent across deploysRunning revision twice without upgradeAlways run alembic upgrade head in deploy scripts — it safely skips applied migrations
Port 8000 exposed directly to internetNo Nginx reverse proxyAlways run Nginx in front of Gunicorn/Uvicorn in production

Hands-On Practice

quick-deploy-test.sh
# 1) Build and start from scratch
docker compose down -v
docker compose up -d --build

# 2) Verify health
sleep 2
curl -s http://localhost:8000/health | python -m json.tool

# 3) Run migrations
docker compose exec app alembic upgrade head

# 4) Check logs for errors
docker compose logs app --tail=20

What's Next