Deploy FastAPI on Bahriya
FastAPI is a modern, high-performance Python web framework built on ASGI. In production you serve it with uvicorn — often supervised by gunicorn using uvicorn workers — listening on port 8000. The same packaging works for a Flask app served through gunicorn. This guide deploys a FastAPI application as an HTTP container.
FastAPI is a modern, high-performance Python web framework built on ASGI. In production you serve it with uvicorn — often supervised by gunicorn using uvicorn workers — listening on port 8000. The same packaging works for a Flask app served through gunicorn. This guide deploys a FastAPI application as an HTTP container.
Only two things change between stacks on Bahriya: the Dockerfile that builds your image, and the port your application listens on. For FastAPI served by uvicorn, that port is 8000.
Dockerfile
This builds on the slim Python base image, installs your requirements, and starts uvicorn bound to 0.0.0.0:8000. Binding to 0.0.0.0 is essential — binding to 127.0.0.1 would leave the process unreachable from outside the container.
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
# Replace "app.main:app" with your module path and app object
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]For heavier workloads, run uvicorn workers under gunicorn instead:
CMD ["gunicorn", "app.main:app", \
"--worker-class", "uvicorn.workers.UvicornWorker", \
"--bind", "0.0.0.0:8000", "--workers", "3"]List fastapi, uvicorn (and gunicorn if you use it) in your requirements.txt. The application logs to standard output, which the platform captures.
The --host 0.0.0.0 rule
Whichever server you choose, it must bind to 0.0.0.0 so the platform's ingress can route requests to it. For uvicorn that is --host 0.0.0.0; for gunicorn it is --bind 0.0.0.0:8000. A process listening only on localhost will fail its health check and never receive traffic.
Deploy from the Console
- Create (or open) a project, then create a container.
- Set the image to your pushed image reference, and the port to
8000. - Set a health check path — a simple
/healthzroute returning 2xx is ideal. - Choose your regions, set CPU and memory, and attach any secrets.
- Create the container and wait for it to reach a running state.
See Deploy your first container for the full walkthrough.
Deploy with the Reis CLI
reis container:create \
--type http \
--name "FastAPI Service" \
--handle fastapi-service \
--image ghcr.io/myorg/fastapi-service:v1.0.0 \
--project my-project \
--port 8000 \
--healthcheck /healthz \
--cpu 500 \
--memory 512 \
--regions falkenstein-1 \
--env APP_ENV=production \
--secrets DATABASE_URL=database-urlSee Deploy an HTTP container with flags for the full flag reference.
Configuration, secrets, and databases
- Non-sensitive configuration — pass log levels, feature flags, and endpoint URLs as plain environment variables.
- Sensitive values — database passwords, API keys, and signing secrets belong in secrets, encrypted at rest and injected as environment variables at runtime. Read them with
os.environor a settings library such as pydantic-settings. - Database connections — connect to your own managed database using a connection URL or discrete credentials supplied through secrets.
Next steps
- Deploy your first container — the end-to-end walkthrough.
- Environment variables — plain config versus secrets.
- Health checks — how the platform decides a deployment is ready.
- HTTP containers — hostnames, autoscaling, and security knobs.