Framework Frankfurt, Germany
Nodion recognizes Django by manage.py and Django in your dependencies. The Python buildpack installs them, runs collectstatic and starts Gunicorn on your project's WSGI module. With a release: line in a Procfile, migrations run before each new version goes live, and the app and its PostgreSQL database run in Frankfurt.
manage.py and Django in your dependenciesgunicorn <project>.wsgi, 3 workerscollectstatic writes. Pin the Python version in .python-version, because a range such as requires-python = ">=3.10" picks the newest release. requirements.txt Django>=5.2
gunicorn
whitenoise
dj-database-url
psycopg[binary] collectstatic runs during the build, where only variables marked Build exist, so the settings must import without runtime secrets. Django checks SECRET_KEY only when it is used. Add WhiteNoise right after SecurityMiddleware. settings.py import os
import dj_database_url
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "")
DEBUG = os.environ.get("DJANGO_DEBUG") == "1"
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "").split(",")
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS if h]
DATABASES = {"default": dj_database_url.config(conn_max_age=600)}
STATIC_ROOT = BASE_DIR / "staticfiles"
# MIDDLEWARE: "whitenoise.middleware.WhiteNoiseMiddleware"
# right after "django.middleware.security.SecurityMiddleware" ALLOWED_HOSTS, so Django would answer 400 and the release never goes live. Put a small middleware first in MIDDLEWARE and set the health check path to /healthz in the app settings. health.py from django.http import HttpResponse
class HealthCheckMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path == "/healthz":
return HttpResponse("ok")
return self.get_response(request) release: line in a Procfile runs once per build, after the build and before the new version starts. If it fails, the deploy stops and the running version stays live. Procfile release: python manage.py migrate --noinput DATABASE_URL on the next deploy. Set DJANGO_SECRET_KEY as a secret and DJANGO_ALLOWED_HOSTS to your app's hostname and your own domains, then push. worker: celery -A myproject worker to the Procfile together with an explicit web: gunicorn myproject.wsgi --bind 0.0.0.0:$PORT; without a web: line the first Procfile entry other than release: becomes the default command. Then add a process named worker without a port on the Processes tab. Valkey in the same region gives you REDIS_URL as broker.web: line, for example with Uvicorn workers, and bind it to 0.0.0.0:$PORT.requirements.txt, poetry.lock and Pipfile.lock are installed as they are. A Pipfile without its lock file installs nothing.DATABASE_URL, REDIS_URL or CLICKHOUSE_URL. release: line runs with every new build. Dockerfile apps, and redeploys or rollbacks to an earlier image, use a release command set on the app itself, which also takes precedence over the Procfile line. On static sites a release step runs in an image that holds only the built files. Only if you ask for it: add release: python manage.py migrate --noinput to a Procfile. It runs once per build before the new version starts, and a failure stops the deploy.
Usually the health check gets a 400 from ALLOWED_HOSTS or a 404 on /. Answer a path such as /healthz in a middleware placed before the host check and set it as the app's health check path.
Yes. With a poetry.lock, Nodion installs Poetry and runs poetry install --only main. Pipenv works with a Pipfile.lock.
In the EU Central region in Frankfurt, Germany. Build, registry, the app and its databases, volumes, buckets, logs and metrics stay in that region, and Nodion's API and control plane are hosted in Germany. Nodion GmbH is based in Stuttgart.
Nodion provides the basis for it: Nodion GmbH is based in Stuttgart, Germany, in the Frankfurt region the app, its databases and volumes run in Germany, and you conclude the data processing agreement (DPA) under Art. 28 GDPR electronically in the dashboard. Whether your setup complies also depends on how you configure and use the app.
An app instance starts at 1 EUR per month. The setup in the cost box costs 3.50 EUR per month: App 2 EUR, PostgreSQL 1.50 EUR. Prices are net and billed per second, and you pick bigger sizes or more instances whenever you need them.
Yes. Every app gets a default hostname with HTTPS. Add your own domain on the app's Domains tab; the TLS certificate is issued and renewed automatically.
Earn up to 15 € in credit when signing up.
or with email
Product news, no spam. Unsubscribe anytime.
Successfully subscribed.