1

I have multiple settings files in my Django project (base.py, local.py, production.py).

Locally, I'm kicking off the Django dev server via

python manage.py runserver --settings=config.settings.local

How can I tell mod_wsgi to use the same file? I'm testing this on my local apache instance, but will need to figure out the same thing for my production apache instance.

--settings=config.settings.production

Current httpd-vhosts.conf:

WSGIDaemonProcess secureDash python-path=/Users/user/projects/secureDash_project/secureDash python-home=/Users/user/.venvs/securedash_py3.6
WSGIProcessGroup secureDash
WSGIScriptAlias / /Users/user/projects/secureDash_project/config/wsgi.py

Error that I see in the apache log:

ModuleNotFoundError: No module named 'secureDash.settings'

Django 1.11

mod_wsgi-4.5.15

Apache 2.4.18

brewcrazy
  • 623
  • 13
  • 30

2 Answers2

0

You do this by setting the DJANGO_SETTINGS_MODULE environment variable. You can either do this in your Apache vhost configuration, or in the wsgi file itself.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • I was going to post essentially the same thing, but for what it's worth, I ended up creating multiple manage.py scripts that each point to a different wsgi.py file (e.g. I have prod-manage.py / jenkins-manage.py / etc. and then corresponding wsgi.py files and settings... ) – Foon Apr 27 '17 at 17:20
  • My preference would be to not have to manage multiple wsgi.py/manage.py scripts. The authors of Two Scoops of Django advises against using Apache environment variables and recommend instead using a "secrets file pattern". I've already implemented this via a JSON file for my secret_key. In the interest of being OS/Sever agnostic as well as managing only 1 wsgi.py, maybe I'll set up DJANGO_SETTINGS_MODULE in that file as well. – brewcrazy Apr 27 '17 at 18:56
  • You cannot set it in the Apache vhost configuration as suggested. Process environment variables cannot be set for WSGI applications hosted by Apache from the Apache configuration file. You can only set per request variables that are passed in the WSGI environ dictionary. That is not the same. – Graham Dumpleton Apr 28 '17 at 01:34
0

I solved this by adding DJANGO_SETTINGS_MODULE to my secrets.json file in each environment.

secrets.json:

{
  "FILENAME": "secrets.json",
  "SECRET_KEY": "someSuperSecretiveSecret!",
  "DJANGO_SETTINGS_MODULE": "config.settings.local"
}

wsgi.py:

import json
from django.core.exceptions import ImproperlyConfigured
from pathlib import Path
...

# Directory Paths
BASE_DIR = Path(__file__).resolve().parent

# JSON-based secrets module
SECRETS_JSON = str(BASE_DIR) + '/secrets.json'

with open(SECRETS_JSON) as f:
    secrets = json.loads(f.read())


def get_secret(setting, secrets=secrets):
    '''Get the secret variable or return explicit exception'''
    try:
        return secrets[setting]
    except KeyError:
        error_msg = 'Set the {0} environment variable'.format(setting)
        raise ImproperlyConfigured(error_msg)


DJANGO_SETTINGS_MODULE = get_secret('DJANGO_SETTINGS_MODULE')

os.environ.setdefault("DJANGO_SETTINGS_MODULE", DJANGO_SETTINGS_MODULE)
brewcrazy
  • 623
  • 13
  • 30
  • You should be careful if using ``os.environ.setdefault`` as that can cause issues with mod_wsgi when hosting multiple Django instances out of the one process. See http://blog.dscpl.com.au/2012/10/requests-running-in-wrong-django.html – Graham Dumpleton Apr 29 '17 at 01:50
  • Thanks for the heads up. My understanding of what you're saying in the blog post is that as long as `WSGIDaemonProcess` is set in the apache vhost config, then using `os.environ.setdefault` should be safe. Is that correct? I have that set, but will also test out your other alternative recommendation to be on the safe side. – brewcrazy Apr 29 '17 at 17:33
  • In addition to ``WSGIDaemonProcess``, you also need to ensure that only one WSGI application is delegated to run in that daemon process group. If you allow more than one WSGI application to run in the one daemon process group (in different sub-interpreters), then same problem can arise. So if you only have the one Django site then fine, otherwise still need to be careful. – Graham Dumpleton Apr 29 '17 at 20:35