Deploy a Python / FastAPI app

A FastAPI service on a live HTTPS URL, with a tiny Dockerfile you can copy as-is.

Dockhold recognises a FastAPI project on every account: a requirements.txt that names fastapi and a main.py at the root that defines app, and it installs the requirements and starts uvicorn main:app on the assigned port. The five-line Dockerfile below is the same recipe, written down, for when you want to pin exactly how the app installs and starts.

In a hurry? Start from the ready-made fastapi-starter template: click Use this template on GitHub, then deploy it. Or follow the steps below to set up a project you already have.

1. Bind uvicorn to the assigned port

A standard FastAPI entrypoint in main.py:

from fastapi import FastAPI

app = FastAPI()

@app.get("/health")
def health():
    return {"status": "ok"}

List your dependencies in requirements.txt:

fastapi
uvicorn[standard]

Your app must listen on 0.0.0.0 and read its port from the PORT environment variable. Never localhost, never a hardcoded port. Dockhold assigns PORT at runtime; an app that ignores it can't receive traffic.

2. Add a minimal Dockerfile

Put this Dockerfile at the repo root:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Shell form so $PORT is expanded at runtime
CMD uvicorn main:app --host 0.0.0.0 --port $PORT

A Dockerfile at the repo root takes priority and tells Dockhold exactly how to build and run the app, with no guesswork. The CMD is in shell form on purpose: that's what lets $PORT expand at runtime.

3. Read config and secrets from the environment

Set plain config in the dashboard and sensitive values as secrets, then read them with os.environ:

import os
api_key = os.environ["SOME_API_KEY"]

4. Add a database (optional)

Enable the managed Postgres add-on and Dockhold injects DATABASE_URL. Read it with os.environ["DATABASE_URL"]. Don't run your own database, and remember the filesystem is wiped on every restart, so persist state in the database, not on disk.

5. Connect the repo and deploy

  1. Push the project (with the Dockerfile) to a GitHub repository.
  2. Open the dashboard, connect GitHub, and pick the repo.
  3. Dockhold builds from your Dockerfile and runs it.

Your app goes live at https://<your-app>.dockhold.app with HTTPS handled for you. Every later push to your main branch redeploys.

Troubleshooting

  • URL times out: the CMD must use --host 0.0.0.0 --port $PORT and be in shell form (no [ ] brackets), or $PORT won't expand.
  • App not found / import error: main:app means a variable named app in main.py. Match the file and variable names to your project.
  • Missing dependency at runtime: add it to requirements.txt: only what's listed there is installed.

Next

Suggested guides
↑↓ to move ↵ to open Esc to close From the Dockhold docs