App hosting ยท Django

Django hosting with gunicorn and a real database

Push the repository, set the build and start commands, give the app an address. Python is detected from requirements.txt, static files are collected in the build, and a managed PostgreSQL is one click when SQLite stops being enough.

Free app
256 MB, Node.js, Python, Go, Java and more
Address
https://name.fadehost.app, sleeps when idle on free
Paid
from $2/mo or $20/yr for 1 GB, with an always-on address included
Regions
France, Montreal, Oregon, Singapore

What the repository needs

  1. requirements.txt with django, gunicorn and whitenoise for static files.
  2. Build command: python manage.py collectstatic --noinput && python manage.py migrate.
  3. Start command: gunicorn project.wsgi -b 0.0.0.0:$PORT.
  4. SECRET_KEY, DEBUG=0, ALLOWED_HOSTS and DATABASE_URL in environment variables.

The database

SQLite at /data/db.sqlite3 survives redeploys and is fine for a small site. For anything with concurrent writes, create a managed PostgreSQL in the panel, put its URL in DATABASE_URL with dj-database-url, and let the build's migrate step apply your migrations on every deploy.

Static and media files

WhiteNoise serves collected static files from the app itself, which is enough behind the Cloudflare proxy. User uploads go under /data/media so they persist; set MEDIA_ROOT there.

Frequently asked questions

Does the admin work?

Yes, at /admin as usual. Create the superuser without a shell: put DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAIL and DJANGO_SUPERUSER_PASSWORD in the environment, add python manage.py createsuperuser --noinput to the build command for one deploy, then take it out again.

CSRF errors behind the proxy?

Add the app's https address (and your domain) to CSRF_TRUSTED_ORIGINS and set SECURE_PROXY_SSL_HEADER to ("HTTP_X_FORWARDED_PROTO", "https").

Which port does the app listen on?

The PORT environment variable, 8080 by default, on 0.0.0.0. A server bound to 127.0.0.1 answers only itself and the web address gets nothing.

How does the public address work?

Give the app a web address in the panel and it is served at https://name.fadehost.app behind the Cloudflare proxy with a certificate. It comes with the plan on every tier. On the free tier the address sleeps when nobody has used it for a while and wakes on the next request; on a paid tier it stays awake. Your own domain can point at it.

What happens on a deploy?

The repository is cloned at your branch, dependencies install, the build runs when there is one, the app starts. With auto-deploy on, every push does the same. The live console shows each step; a failed one is explained in plain words.

Related

Django hosting with gunicorn and a real database

Deploy a Django app free