Deploy a Python / FastAPI app
A FastAPI service on a live HTTPS URL, with a tiny Dockerfile you can copy as-is.
For Python the most reliable, reproducible path is a five-line Dockerfile — it pins exactly how the app installs and starts, so it deploys the same way every time. This recipe is the whole path.
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 — 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 secrets in the Vault, 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
- Push the project (with the
Dockerfile) to a GitHub repository. - Open the dashboard, connect GitHub, and pick the repo.
- 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
CMDmust use--host 0.0.0.0 --port $PORTand be in shell form (no[ ]brackets), or$PORTwon't expand. - App not found / import error:
main:appmeans a variable namedappinmain.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
- Add a frontend
- Agent rules — make your AI tool generate Dockhold-ready apps.
- All recipes