Deploy Django in Europe
Django on EU infrastructure, under an EU company: collectstatic at build time, gunicorn at run time, managed Postgres linked in, migrations before traffic switches.
Django is easy to host and easy to host badly. HostStack builds the production shape for you: dependencies with pip, static files collected during the build, gunicorn in front of your WSGI app, and migrations run inside the new release before it takes traffic. It all runs in Helsinki, under a Danish company, which is the short answer to a European customer’s GDPR questionnaire.
What HostStack detects and builds
- Django is recognised from manage.py plus django in requirements.txt or pyproject.toml.
- Dependencies install with pip install -r requirements.txt, or pip install . when there is only a pyproject.toml.
- The build runs python manage.py collectstatic --noinput.
- gunicorn serves the WSGI module it finds — the first folder holding both wsgi.py and settings.py — with two workers, bound to the port in PORT. gunicorn itself must be in your requirements.
- The Python version comes from .python-version, runtime.txt, .tool-versions, Pipfile, requires-python or Poetry’s python dependency; with none, the newest release.
| Step | Default when you leave it empty |
|---|---|
| Install | pip install -r requirements.txt (or pip install .) |
| Build | python manage.py collectstatic --noinput |
| Start | gunicorn --bind 0.0.0.0:$PORT --workers 2 <project>.wsgi:application |
| Port | PORT=3000 unless you set another — gunicorn binds it |
The dashboard pre-fills these commands when it detects Django, and the build applies them to any command left empty. If you write your own start command, as the file below does, keep $PORT in it: the platform routes to the port it injects.
hoststack.yaml for Django
Optional. Commit it next to your code and every deploy applies it; leave a key out and the service keeps its dashboard value. It configures a service that already exists — it never creates one. The full schema and hoststack validate are in the docs.
services:
web:
install:
command: pip install -r requirements.txt
build:
command: python manage.py collectstatic --noinput
start:
command: gunicorn mysite.wsgi:application --bind 0.0.0.0:$PORT --workers 2
healthCheck:
path: /healthz/
env:
DJANGO_SETTINGS_MODULE: mysite.settings
PYTHONUNBUFFERED: "1"Replace mysite with your project package. The health-check path must answer 2xx or 3xx — add a tiny view for it, or drop the healthCheck block if your / does.
Database and environment variables
Linking a managed Postgres injects DATABASE_URL. Django does not read it on its own; dj-database-url turns it into the DATABASES setting in one line: DATABASES = {"default": dj_database_url.config(conn_max_age=600)}.
hoststack db create --project prj_... --name app-db --engine postgres --plan micro
hoststack db link db_... --service svc_...
hoststack env set svc_... DJANGO_SECRET_KEY=... --secret
hoststack services update svc_... --pre-deploy-command "python manage.py migrate --noinput"Secrets belong on the service, not in the file — see environment variables and databases.
Deploy Django step by step
- 1Add gunicorn, dj-database-url and whitenoise to requirements.txt, and read SECRET_KEY, DEBUG and ALLOWED_HOSTS from the environment.
- 2Create a web service from your repository, in the dashboard or with hoststack services create --name web --type web_service --project prj_... --repo acme/app.
- 3Commit the hoststack.yaml above with your project package in place of mysite.
- 4Create a managed Postgres and link it; DATABASE_URL is injected on the next deploy.
- 5Set python manage.py migrate --noinput as the pre-deploy command, so migrations run before the new release takes traffic.
- 6Push to deploy, then add your domain and include it in ALLOWED_HOSTS.
Hosted in Europe, by a European company
Django apps tend to be the system of record — user accounts, admin, the data a DPO asks about. Keeping the app, the Postgres behind it and the nightly backups in one EU region, with an EU company as processor, means there is no third-country transfer to document.
Every service, database and backup runs in Helsinki, Finland, on Hetzner, and HostStack is operated by MICCI, a Danish company — so the US CLOUD Act has no hold on it, the GDPR data processing agreement is signed at signup on every plan, and the invoice is in EUR. Why that differs from a US platform's EU region is on EU data residency.
Things that catch people out
collectstatic runs without your secrets.
Secret variables never reach the build, so settings.py must import cleanly without them: give SECRET_KEY a fallback such as os.environ.get("DJANGO_SECRET_KEY", "build-only"), and set STATIC_ROOT.
gunicorn does not serve static files.
Add WhiteNoise to MIDDLEWARE so the collected files are served by the app itself. User uploads belong on a persistent disk or object storage — the root filesystem is read-only.
ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS.
Include the service’s *.hoststack.dev host and your custom domain, or Django answers 400 — including to the health check.
Poetry and uv lockfiles are not used for the install.
With no requirements.txt, the build runs pip install . from pyproject.toml. To install exactly what your lockfile pins, export it to requirements.txt or set your own install command.
Frequently asked questions
How do I deploy Django in Europe?
Push the repo to HostStack: it detects Django from manage.py and your requirements, installs with pip, runs collectstatic, and serves the app with gunicorn in Helsinki, Finland. Link a managed Postgres for DATABASE_URL and set python manage.py migrate as the pre-deploy command.
Does HostStack run Django migrations automatically?
It runs the pre-deploy command you set — python manage.py migrate --noinput — inside the new release after it passes its health check and before it takes traffic. If the migration fails or runs longer than 10 minutes, the deploy fails and the previous release keeps serving.
Can I run Celery workers and Celery beat?
Yes. Create a Worker service from the same repo with celery -A mysite worker as its start command, and link a managed Redis for REDIS_URL as the broker. Periodic tasks can run as Cron Job services instead of beat.
Is it GDPR-compliant to host Django on HostStack?
HostStack is operated by MICCI, a Danish company, and runs every service, database and backup in Finland. The data processing agreement is part of signup on every plan and the sub-processor list is published. Your own compliance still depends on what your app does with the data.
Other stacks
All guides are on the deploy guides index. Moving an existing Django app? The Heroku and Render guides have the cutover order.