How to Deploy a FastAPI App for Free (2026, with PostgreSQL)
Deploy FastAPI with Uvicorn workers bound to PORT, async PostgreSQL via SQLAlchemy and settings from the environment, starting on a free plan with HTTPS.
- Published
- Reading time
- 3 min
On this page
Key takeaways
- In production, run FastAPI with Uvicorn workers bound to 0.0.0.0 and the PORT environment variable.
- Load configuration from environment variables with pydantic-settings, and the database from DATABASE_URL.
- DockHosting detects FastAPI from requirements.txt or pyproject.toml, runs it with async workers and gives you HTTPS.
FastAPI makes building an API fast. Deploying it means choosing a server process, binding the right address, managing settings and connecting a database. This guide takes a FastAPI app to a production HTTPS URL.
1. A minimal production-ready app
# main.py
from fastapi import FastAPI
app = FastAPI(title="My API")
@app.get("/health")
async def health():
return {"status": "ok"}
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}# requirements.txt
fastapi
uvicorn[standard]
pydantic-settings
sqlalchemy
psycopg[binary]A /health endpoint costs nothing and makes debugging deploys much easier.
2. The start command
In production, Uvicorn has to listen on all interfaces and on the port the platform assigns:
uvicorn main:app --host 0.0.0.0 --port $PORT --workers 2Or with Gunicorn managing Uvicorn workers:
gunicorn main:app -k uvicorn.workers.UvicornWorker -w 2 -b 0.0.0.0:$PORTOn DockHosting, FastAPI is detected from fastapi in your requirements and runs under Uvicorn/Gunicorn with async workers. You can override the start command in the project settings, and start commands with $ variables like $PORT work.
3. Settings from the environment
pydantic-settings reads and validates configuration, and fails at startup with a clear message when something is missing:
# settings.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
api_key: str
debug: bool = False
settings = Settings() # reads DATABASE_URL, API_KEY, DEBUGIf a variable is missing, the crash message names the invalid field, and DockHosting shows that message in the deploy's App output tab.
4. PostgreSQL with async SQLAlchemy
Attach a managed PostgreSQL database in the dashboard, and DATABASE_URL is injected over the private network.
# db.py
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from settings import settings
url = settings.database_url.replace("postgresql://", "postgresql+psycopg://", 1)
engine = create_async_engine(url, pool_pre_ping=True)
Session = async_sessionmaker(engine, expire_on_commit=False)pool_pre_ping replaces dropped connections quietly, which is useful when Free-plan apps wake up from sleep. Run Alembic migrations as part of your start command, for example alembic upgrade head && uvicorn ….
5. Deploy
curl -fsSL https://cli.dockhosting.dev/install.sh | sh # Windows: irm https://cli.dockhosting.dev/install.ps1 | iex
dock login
dock deployYou get https://<project>.dockhosting.cloud with automatic HTTPS, and your interactive docs at /docs. Add API_KEY and any other settings as environment variables, then run dock restart.
6. CORS for a frontend
If a React or Vue app on another domain calls your API, allow its origin explicitly:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://myapp.dockhosting.cloud"],
allow_methods=["*"],
allow_headers=["*"],
)Avoid allow_origins=["*"] together with credentials. Browsers reject it, and it's unsafe.
Plans
The Free plan runs a FastAPI app with a PostgreSQL database at $0. It sleeps after 1 hour without requests and wakes on the next one. For an API that real users depend on, Hobby ($4/month) is always on and adds your own domain. See pricing.
Getting a 502? Check the 8 most common causes. Building with Django instead? See the Django deploy guide.
Frequently asked questions
Should I use Uvicorn or Gunicorn for FastAPI in production?
Both work. Uvicorn alone with --workers is simple and fine for most apps. Gunicorn with Uvicorn workers adds process management. On DockHosting the start command is set for you and you can override it.
Why is my FastAPI docs page (/docs) blank in production?
Usually a proxy or root_path issue. If you serve the app under a sub-path, set root_path. When the app is served at the root of its own domain, /docs works without changes.
Which Python versions are supported?
Python 3.11 and 3.12, with pip (requirements.txt) or Poetry (pyproject.toml).
- FastAPI
- Python
- API
- Deployment
- Tutorial
Written by Doughmi ILYAS
Doughmi builds DockHosting, the developer-first platform behind dock deploy: the build system, the managed databases and the dashboard. On this blog: guides to shipping apps without running servers, written with the commands the platform actually ships.
