Django on CloudMagnus

Django installed with the database wired in. You handle migrations and start the gunicorn process.

What our scaffold installs

  • A virtualenv at /home/<siteUser>/venv/
  • pip install django gunicorn psycopg2-binary in the venv (latest stable versions of each)
  • django-admin startproject app htdocs, creating the standard Django project layout in your htdocs/
  • An override appended to htdocs/app/settings.py with DATABASES pointing at the Postgres DB we just provisioned (host 127.0.0.1, the right database name and user, password reaches the file via a sudo'd tee heredoc so it's never in argv)
  • ALLOWED_HOSTS set to your domain and www.<domain>
  • A Postgres database scoped to your site, owned by a per-site Postgres user
  • An allocated port from the 8000-8999 pool
  • nginx vhost reverse-proxying your domain to 127.0.0.1:<allocatedPort>

What you do next

  1. SSH in.
  2. Activate the venv: source ~/venv/bin/activate.
  3. Run migrations: cd htdocs && python manage.py migrate.
  4. Create a superuser if you want to use Django admin: python manage.py createsuperuser.
  5. Start gunicorn on the allocated port: gunicorn --bind 127.0.0.1:<port> app.wsgi:application --chdir htdocs.

Visit your domain. The Django default landing page is waiting.

Static files

Django doesn't serve static files in production. Two options:

  • WhiteNoise (simplest): pip install whitenoise, add it to MIDDLEWARE, run python manage.py collectstatic. WhiteNoise serves the collected files efficiently from your gunicorn process.
  • nginx serving directly: contact support for the vhost edit. We add a location /static/ block pointing at your htdocs/static/ directory.

Media uploads

Django's MEDIA_ROOT defaults to /path/to/media/. Set it to /home/<siteUser>/htdocs/media/ in settings.py. Same nginx caveat as static files for serving.

Process management

Same story as Node and Python generic. You keep gunicorn running. Use nohup or install supervisor per-site.

Common Django issues

"DisallowedHost"

You hit your site at a domain not in ALLOWED_HOSTS. Add it. Common case: you set up the site at example.com but visited www.example.com and forgot to add the www variant. Our scaffold adds both, so this usually only hits when you change domains later.

500 errors with no detail

Django's DEBUG = False in production hides errors. Check logs/ over SFTP for the gunicorn error log; the traceback is there.

"OperationalError: could not connect to server"

Database connection failed. Confirm settings.py's DATABASES block matches what's in the dashboard for your site. If you regenerated settings.py manually, our DB override may have been clobbered.

Migrations refuse to run

Either the DB user doesn't have permissions (our scaffold grants ALL on the per-site database), or there's a model conflict. Try python manage.py migrate --fake-initial if you've imported existing data; otherwise check the migration error message.

What CloudMagnus doesn't do for Django

  • Run migrate on deploy. You handle it.
  • Run collectstatic. Same.
  • Manage gunicorn or supervisor. SSH and configure.
  • Provide Celery workers for background tasks. Roll your own with the same caveat as Node's process management.