Framework guide

How to deploy a Python app: FastAPI, Django or Flask

To deploy a FastAPI, Django or Flask app on Codara Cloud, commit a requirements.txt or pyproject.toml, make the server listen on 0.0.0.0 and the PORT variable, and create an app from the GitHub repository. Codara builds it with Railpack, which detects common layouts and starts uvicorn or gunicorn for you. For any other layout, set the start command in a railpack.json file.

By Codara Solutions · Reviewed

What does Codara need from a Python project?

A dependency file at the root of the repository: requirements.txt, pyproject.toml or a Pipfile. A uv.lock or poetry.lock next to pyproject.toml tells Railpack to install with uv or Poetry. Pin the Python version in a .python-version file.

Your web server must listen on all interfaces and on the port in the PORT environment variable, which Codara sets (8080 unless you choose another port). uvicorn needs --host 0.0.0.0 --port $PORT. gunicorn binds to 0.0.0.0:$PORT on its own when PORT is set.

.python-version
3.12

Which start command does Codara use?

Railpack recognises three common layouts and writes the start command itself. For anything else, add a railpack.json file at the root with your own start command; it takes precedence over the detected one.

railpack.json · FastAPI app in app/main.py
{
  "deploy": {
    "startCommand": "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-8080}"
  }
}
Start commands Railpack detects, and when
FrameworkDetected whenStart command
FastAPIfastapi and uvicorn are dependencies and the app object is app in main.py at the rootuvicorn main:app --host 0.0.0.0 --port ${PORT:-8000}
Flaskgunicorn is a dependency and the app object is app in main.py at the rootgunicorn --bind 0.0.0.0:${PORT:-8000} main:app
Djangomanage.py is at the root and django is a dependency; add gunicorn toopython manage.py migrate && gunicorn --bind 0.0.0.0:${PORT:-8000} <project>.wsgi:application
Anything elseYour own layout, e.g. app/main.pyThe deploy.startCommand in railpack.json

How do you create the app?

Install the Codara GitHub App on the repository’s owner and create a project. In the console, open Apps → New app, choose the project and environment, select GitHub repository and the branch, and submit. The wizard creates the app and starts its first build; every later push to the branch deploys again. Set a health check path, such as /health, in the app’s settings.

Terminal · the same from the CLI
codaracloud apps create api --client my-workspace --project research \
  --repo acme/research-api --branch main
codaracloud deploy api --client my-workspace --project research --source

codaracloud logs api --follow

How do you connect Postgres and run migrations?

Create a Postgres database in the same environment and connect it to the app: Codara injects DATABASE_URL and DATABASE_DIRECT_URL and restarts the app. Read the connection URL from DATABASE_URL in your code; in Django, dj-database-url does it for you.

Run migrations as the app’s pre-deploy command, for example alembic upgrade head or python manage.py migrate. It runs once in the new image before traffic moves, and a failure keeps the current release serving. Railpack’s default Django command also runs migrate each time a container starts; if you prefer migrations only in the pre-deploy command, set your own start command in railpack.json.

settings.py · Django
import os
import dj_database_url

DATABASES = {"default": dj_database_url.config(conn_max_age=600)}
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "").split(",")
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS if h]

Set ALLOWED_HOSTS to your codara.cloud hostname and your own domain as a runtime variable, and SECRET_KEY as a secret. For static files, WhiteNoise is the usual choice with one container: run python manage.py collectstatic --noinput in your start command before gunicorn.

Where do Celery workers and scheduled tasks go?

A Celery or RQ worker is a separate service in the same environment, built from the same repository with its own start command. Codara also runs managed Redis for the broker. Scheduled work, such as a nightly report or a cleanup script, belongs in a Codara job with a cron expression rather than a sleeping loop in the web process.

Questions

Do I need a Dockerfile for a Python app?
No. Railpack builds Python apps from requirements.txt, pyproject.toml or a Pipfile. Add a Dockerfile only if you need system libraries or a base image of your own; Codara then uses it as written.
Why does my app work locally but not on Codara?
Usually the server listens on 127.0.0.1 or on a fixed port. Bind to 0.0.0.0 and to the PORT variable, and check the app’s logs after a release.
Can I use uv or Poetry?
Yes. With pyproject.toml, a uv.lock makes Railpack install with uv and a poetry.lock with Poetry.

Keep going