Client Area

FastAPI Production Deployment on DomainIndia VPS (Gunicorn + Uvicorn + nginx + PostgreSQL)

ByDomain India Team·DomainIndia Engineering
4 min read24 Apr 20264 views
# FastAPI Production Deployment on DomainIndia VPS (Gunicorn + Uvicorn + nginx + PostgreSQL)
TL;DR
FastAPI is the dominant Python API framework of 2026 — async-first, type-safe, auto-OpenAPI docs. This guide deploys a production FastAPI app on DomainIndia VPS: Uvicorn workers under Gunicorn, systemd, nginx reverse proxy, PostgreSQL with SQLAlchemy, Alembic migrations, and zero-downtime reloads.
## Why FastAPI - Async-first (handles 10K+ concurrent connections) - Pydantic for type-safe request/response models - Auto-generated OpenAPI/Swagger docs at `/docs` - 3-5× faster than Flask, same-league as Node.js Express - Massive ecosystem (SQLAlchemy 2, Alembic, Celery, APScheduler) Good fit: REST APIs, WebSocket services, ML inference endpoints. Less ideal for server-rendered HTML apps — use Django or Flask for those. ## Stack we're deploying ``` Client → nginx (443) → Gunicorn → 4× Uvicorn workers → FastAPI app → PostgreSQL ↑ Redis (cache/queue) ``` ## Step 1 — Prepare VPS ```bash # AlmaLinux 9 sudo dnf install -y python3.12 python3.12-devel python3-pip nginx postgresql-server postgresql-contrib redis git certbot python3-certbot-nginx # Ubuntu 22.04+ sudo apt install -y python3.12 python3.12-venv python3-pip nginx postgresql redis git certbot python3-certbot-nginx # Create app user sudo useradd -r -m -s /bin/bash fastapi sudo su - fastapi ``` ## Step 2 — Sample FastAPI app `~fastapi/app/main.py`: ```python from contextlib import asynccontextmanager from fastapi import FastAPI, Depends, HTTPException from fastapi.responses import JSONResponse from sqlalchemy.ext.asyncio import AsyncSession from pydantic import BaseModel, EmailStr import os from .db import get_db, engine from .models import User @asynccontextmanager async def lifespan(app: FastAPI): # Startup print("Starting up") yield # Shutdown await engine.dispose() print("Shutting down") app = FastAPI( title="MyAPI", version="1.0.0", lifespan=lifespan, ) class UserCreate(BaseModel): email: EmailStr name: str class UserOut(BaseModel): id: str email: str name: str class Config: from_attributes = True @app.get("/health") async def health(): return {"status": "ok", "version": "1.0.0"} @app.post("/users", response_model=UserOut) async def create_user(payload: UserCreate, db: AsyncSession = Depends(get_db)): user = User(email=payload.email, name=payload.name) db.add(user) await db.commit() await db.refresh(user) return user @app.get("/users/{user_id}", response_model=UserOut) async def get_user(user_id: str, db: AsyncSession = Depends(get_db)): user = await db.get(User, user_id) if not user: raise HTTPException(404, "Not found") return user ``` `~fastapi/app/db.py`: ```python from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker import os DATABASE_URL = os.getenv("DATABASE_URL") # postgresql+asyncpg://... engine = create_async_engine(DATABASE_URL, pool_size=10, max_overflow=5) SessionLocal = async_sessionmaker(engine, expire_on_commit=False) async def get_db(): async with SessionLocal() as session: yield session ``` `~fastapi/app/models.py`: ```python import uuid from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy import String class Base(DeclarativeBase): pass class User(Base): __tablename__ = "users" id: Mapped[str] = mapped_column(String, primary_key=True, default=lambda: str(uuid.uuid4())) email: Mapped[str] = mapped_column(String(255), unique=True) name: Mapped[str] = mapped_column(String(100)) ``` `~fastapi/requirements.txt`: ``` fastapi==0.114.0 uvicorn[standard]==0.30.6 gunicorn==22.0.0 sqlalchemy==2.0.35 asyncpg==0.29.0 alembic==1.13.2 pydantic[email]==2.8.2 python-dotenv==1.0.1 ``` ## Step 3 — Install + setup venv ```bash cd ~fastapi python3.12 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## Step 4 — PostgreSQL ```bash # As root sudo postgresql-setup --initdb sudo systemctl enable --now postgresql sudo -u postgres psql <
ToolBest forComplexity
FastAPI BackgroundTasksShort tasks triggered by requestZero — built-in
APSchedulerCron-like schedules in-processLow
Celery + RedisHeavy async work, multiple workersMedium
ArqLightweight async task queueLow
Start with `BackgroundTasks` for simple needs; scale to Celery or Arq when you need retries + multiple worker machines. ## Common pitfalls ## FAQ
Q Flask, FastAPI, or Django?

FastAPI for modern APIs (async, typed, OpenAPI). Django for full-stack with templates, admin, ORM. Flask if you're maintaining existing Flask apps.

Q Uvicorn alone or Gunicorn + Uvicorn?

Uvicorn alone works for dev + light prod. Gunicorn adds process management, graceful reload, better logging — use it for production.

Q Can I run this on DomainIndia shared hosting?

Shared cPanel's Setup Python App runs simple FastAPI apps (via Passenger). For async + multiple workers, use VPS.

Q Asyncpg or psycopg3?

Asyncpg is faster but less feature-complete. Psycopg3 (async mode) is more versatile, supports synchronous adapters. For greenfield FastAPI: asyncpg.

Q How many concurrent requests on a 2 GB VPS?

With 4 Uvicorn workers × 1000 connections each = 4K theoretical. Real-world with DB-backed API: 500-2000/sec. Bottleneck is usually Postgres.

FastAPI in production wants a solid VPS with PostgreSQL. Order VPS

Was this article helpful?

Your feedback helps us improve our documentation

Still need help? Submit a support ticket