Flask and FastAPI
Deploy a Flask or FastAPI app on Ruust: served by Gunicorn or Uvicorn, bound to $PORT on 0.0.0.0, on HTTPS.
Ruust runs your Python web app as an Egg: a long-running server, always on, with no cold starts. Nixpacks auto-detects a Python project from a requirements.txt (or pyproject.toml) at the repo root, installs your dependencies and lays the Egg. If your repo has a Dockerfile, Ruust builds that instead. This page covers Flask served by Gunicorn and FastAPI served by Uvicorn.
Deploy it
- Pin your dependencies in
requirements.txt(includegunicornfor Flask, oruvicornfor FastAPI). - Add a
Procfileat the repo root with aweb:line so Ruust knows how to start the server. - Push your app to a Git repo.
- In the dashboard, choose New Egg, connect the repo and pick a Coop.
- Pick a size and a region (London, Virginia, or your own byo host), then lay the Egg.
Dependencies
Ruust installs from requirements.txt. Include your framework and its server: Gunicorn for Flask, Uvicorn for FastAPI.
flask
gunicorn
# or, for FastAPI:
fastapi
uvicorn[standard]The port
Ruust sets a PORT env var. Your server must listen on it and bind to 0.0.0.0, not localhost (127.0.0.1). Binding to the wrong address is the top reason an Egg builds but never hatches: the process starts, but nothing outside the container can reach it. Do not use the built-in development server (flask run, or uvicorn with --reload) in production. Pin the start command with a web: line in a Procfile at the repo root.
web: gunicorn app:app -b 0.0.0.0:$PORTweb: uvicorn main:app --host 0.0.0.0 --port $PORTEnvironment variables
Set env vars on the Egg for secrets like SECRET_KEY and DATABASE_URL. They are available at both build and run time, encrypted at rest, and never printed in logs. Read them with os.environ in your app.
import os
DATABASE_URL = os.environ["DATABASE_URL"]
SECRET_KEY = os.environ["SECRET_KEY"]Custom domains and networking
Every Egg gets a <name>.<region>.ruust.run URL on HTTPS. To use your own domain, add it to the Egg, point the DNS record shown, and Ruust issues and renews TLS automatically. If your API talks to a database or another service Egg in the same Coop, turn on private networking and peer the two Eggs: connected Eggs reach each other by a private hostname. It is deny-by-default, so only Eggs you explicitly connect can talk.