Appearance
Python: FastAPI, Django, Flask
Python projects have no Dockerfile-free framework detection in the Fjordrun builder; they fall back to Nixpacks, which detects Python from requirements.txt, pyproject.toml (pip, Poetry, PDM, uv), Pipfile or setup.py and installs the dependencies. The build log shows Fjordrun builder: ... building with Nixpacks.
For full control, add a Dockerfile instead.
Two rules
- Set a start command in Settings → Deploy (or add a
Procfilewith aweb:line, which Nixpacks reads). - Listen on
0.0.0.0:$PORT. Fjordrun setsPORT(8080 by default for web services).
FastAPI
requirements.txt:
text
fastapi
uvicorn[standard]Start command:
bash
uvicorn main:app --host 0.0.0.0 --port $PORTFor several workers: gunicorn main:app -k uvicorn.workers.UvicornWorker -b 0.0.0.0:$PORT -w 2 (add gunicorn to the requirements).
Django
requirements.txt with django, gunicorn and your database driver (psycopg[binary] for PostgreSQL).
Start command (mysite is your project package):
bash
python manage.py migrate && gunicorn mysite.wsgi --bind 0.0.0.0:$PORTSettings to check:
python
import os
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "").split(",")
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS if h]
SECRET_KEY = os.environ["SECRET_KEY"]
DEBUG = FalseVariables:
bash
ALLOWED_HOSTS=${{FJORDRUN_PUBLIC_DOMAIN}}
SECRET_KEY=${{secret(50)}}
DATABASE_URL=${{Postgres.DATABASE_URL}}${{secret(50)}} is replaced once by a random 50-character value when you save it. To read DATABASE_URL, use dj-database-url or parse it yourself.
Static files: serve them with WhiteNoise and run collectstatic in the build, for example with the custom build command python manage.py collectstatic --noinput.
Flask
bash
gunicorn app:app --bind 0.0.0.0:$PORT(app:app is module:variable; add gunicorn to the requirements.) Do not use flask run in production.
Python version
Nixpacks reads .python-version or runtime.txt. Service variables are not available during Nixpacks builds, only at runtime; see Build variables.
Using a Dockerfile
dockerfile
FROM python:3.13-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m app && chown -R app /app
USER app
ENV PORT=8080
CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port ${PORT}"]Workers and cron jobs
A Celery or RQ worker is a second service from the same repository with kind worker and a start command such as celery -A mysite worker -l info. Scheduled jobs can be a cron service with a schedule and a start command such as python manage.py clearsessions.