FastAPI server setup

Setting up a FastAPI Server that actually works

Category: devops

Skip the tutorials that break in production. Here's how to set up FastAPI properly from day one.


Most FastAPI tutorials get you running in 5 minutes. Then you spend 5 hours figuring out why it breaks in production.

We've deployed dozens of FastAPI servers. Here's what actually works.

The setup that doesn't lie to you

First, forget uvicorn main:app --reload for anything beyond your laptop. Here's the production-ready structure:

your-api/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ main.py
โ”‚   โ”œโ”€โ”€ models/
โ”‚   โ”œโ”€โ”€ routers/
โ”‚   โ””โ”€โ”€ dependencies.py
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ docker-compose.yml
โ””โ”€โ”€ gunicorn.conf.py

gunicorn.conf.py is the real MVP

This file is where tutorials fail you:

bind = "0.0.0.0:8000"
workers = 4
worker_class = "uvicorn.workers.UvicornWorker"
max_requests = 1000
max_requests_jitter = 50
preload_app = True
timeout = 30
keepalive = 2

Why these settings matter:

  • max_requests prevents memory leaks from killing your server

  • preload_app saves memory when you scale workers

  • timeout = 30 because your database queries will sometimes be slow

Environment variables that don't suck

Use Pydantic's BaseSettings. It's not optional:

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str
    secret_key: str
    debug: bool = False

    class Config:
        env_file = ".env"

Docker that works

Multi-stage builds aren't just for show-offs:

FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
CMD ["gunicorn", "app.main:app"]

The part nobody talks about

Health checks. Your container orchestrator needs to know if your app is actually working:

@app.get("/health")
def health_check():
    return {"status": "healthy", "timestamp": datetime.utcnow()}

Add this to your Docker Compose:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
  interval: 30s
  timeout: 10s
  retries: 3

What we learned the hard way

After deploying FastAPI in production for 3 years:

  • CORS will bite you. Configure it early, not when your frontend team starts swearing.

  • Database connections leak. Use connection pooling from day one.

  • Logs matter. Structure them. Your future debugging self will thank you.

  • Version your API. /v1/ in the URL saves relationships later.

Skip the pain. Start with this setup.

Log in to like this article, or create an account .
0 reads

ยฉ 2026 @Tdude. Alla rรคttigheter fรถrbehรฅllna.