Django
Deploy a Django app on Ruust: built with Nixpacks, served by Gunicorn, with migrations run on each deploy.
Ruust does no framework detection of its own: it hands your repo to Nixpacks (or to your Dockerfile), and it is Nixpacks that detects Python and Django from requirements.txt and a manage.py at the repo root, then builds it (no configuration needed). You serve the app with Gunicorn against your project’s WSGI callable. Because an Egg is a long-running server that is always on, background work and server-side rendering keep working with no cold starts. If you keep a Dockerfile at the repo root, Ruust builds that instead of using Nixpacks. Pin your dependencies in requirements.txt, including gunicorn, your database driver and whitenoise for static files.
Django>=5.0
gunicorn>=22.0
dj-database-url>=2.1
whitenoise>=6.6
psycopg[binary]>=3.1Deploy it
- Push your app to a Git repo with
requirements.txt,manage.pyand aProcfileat the root. - In the dashboard, choose New Egg and connect the repo.
- Add the environment variables below on the Egg (
SECRET_KEY,ALLOWED_HOSTS,DATABASE_URL,DEBUG=False). - Pick a size and a region (London or Virginia), then lay the Egg.
- Watch it incubate, hatch and go live on its
<name>.<region>.ruust.runURL.
The port
Ruust sets a PORT env var and your app must listen on it and bind to 0.0.0.0 (not localhost or 127.0.0.1). Binding to the wrong address is the top reason an Egg builds but never hatches. A Procfile at the repo root pins the start command: put your build-time collectstatic and migrate steps on a release: line, then run Gunicorn on the web: line with -b 0.0.0.0:$PORT so it honours the contract. The web: line is honoured by the Nixpacks build, which bakes it into the image as the start command at build time, not by Ruust itself, and is ignored when you supply your own Dockerfile.
release: python manage.py collectstatic --noinput && python manage.py migrate --noinput
web: gunicorn myproject.wsgi -b 0.0.0.0:$PORTEnvironment variables and settings
Set your configuration as environment variables on the Egg. They are available at build and run time, encrypted at rest and never printed in logs. Read them in settings.py: keep DEBUG=False in production, set SECRET_KEY from the environment, list your hostnames in ALLOWED_HOSTS (comma-separated), and parse DATABASE_URL with dj-database-url. Set DJANGO_SETTINGS_MODULE only if your settings module is not the default myproject.settings.
import os
import dj_database_url
SECRET_KEY = os.environ['SECRET_KEY']
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')
DATABASES = {
'default': dj_database_url.config(conn_max_age=600),
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...the rest of your middleware
]
STATIC_ROOT = BASE_DIR / 'staticfiles'
CSRF_TRUSTED_ORIGINS = ['https://' + h for h in ALLOWED_HOSTS if h]