Emayla
Emayla

Reputation: 53

DJANGO_SETTINGS_MODULE envar not getting set

I am currently developing an application in Python 3.6 and Django 1.11, on the production server (Ubuntu 16.04) I am using Apache2.

I am trying to use separated settings for production and development. Instead of a file, I have a settings directory with base setttings, and production and development settings file, which import the base settings and potentially override them. To let Django know which settings to use, I am setting the DJANGO_SETTINGS_MODULE to either prehranske_oznacbe.settings.development or prehranske_oznacbe.settings.production. This works fine for development. Concerning setting the envvars on the production server, I followed the answers to these two SO: Access Apache SetEnv variable from Django wsgi.py file, Django + mod_wsgi. Set OS environment variable from Apache's SetEnv.

The problem is, when I try to acces my application, I get a 500 Internal Error. The apache error logs:

mod_wsgi (pid=404): Target WSGI script '/home/inesmersak/prehranske_oznacbe/prehranske_oznacbe/wsgi.py' cannot be loaded as Python module.
mod_wsgi (pid=404): Exception occurred processing WSGI script '/home/inesmersak/prehranske_oznacbe/prehranske_oznacbe/wsgi.py'.
Traceback (most recent call last):
   File "/home/inesmersak/prehranske_oznacbe/prehranske_oznacbe/wsgi.py", line 25, in <module>
     application = WSGIEnvironment()
   File "/home/inesmersak/prehranske_oznacbe/venv/lib/python3.5/site-packages/django/core/handlers/wsgi.py", line 151, in __init__
     self.load_middleware()
   File "/home/inesmersak/prehranske_oznacbe/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 48, in load_middleware
     if settings.MIDDLEWARE is None:
   File "/home/inesmersak/prehranske_oznacbe/venv/lib/python3.5/site-packages/django/conf/__init__.py", line 56, in __getattr__
     self._setup(name)
   File "/home/inesmersak/prehranske_oznacbe/venv/lib/python3.5/site-packages/django/conf/__init__.py", line 39, in _setup
     % (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting MIDDLEWARE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

as if the envvar DJANGO_SETTINGS_MODULE is not getting set. My code:

/etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /static /home/inesmersak/prehranske_oznacbe/static
    <Directory /home/inesmersak/prehranske_oznacbe/static>
        Require all granted
    </Directory>

    <Directory /home/inesmersak/prehranske_oznacbe/prehranske_oznacbe>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    WSGIDaemonProcess prehranske_oznacbe python-path=/home/inesmersak/prehranske_oznacbe python-home=/home/inesmersak/prehranske_oznacbe/venv
    WSGIProcessGroup prehranske_oznacbe
    WSGIScriptAlias / /home/inesmersak/prehranske_oznacbe/prehranske_oznacbe/wsgi.py

    # Envvars for Django aplication 'Prehranske oznacbe'.
    SetEnv DJANGO_SETTINGS_MODULE prehranske_oznacbe.settings.production
    SetEnv OZNACBE_API_USERNAME (redacted)
    SetEnv OZNACBE_API_PASSWORD (redacted)
    SetEnv OZNACBE_SECRET_KEY (redacted)
</VirtualHost>

wsgi.py

import os
import django
from django.core.handlers.wsgi import WSGIHandler


class WSGIEnvironment(WSGIHandler):
    def __call__(self, environ, start_response):
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'prehranske_oznacbe.settings.production')
        os.environ['DJANGO_SETTINGS_MODULE'] = environ['DJANGO_SETTINGS_MODULE']
        os.environ['OZNACBE_SECRET_KEY'] = environ['OZNACBE_SECRET_KEY']
        os.environ['OZNACBE_API_USERNAME'] = environ['OZNACBE_API_USERNAME']
        os.environ['OZNACBE_API_PASSWORD'] = environ['OZNACBE_API_PASSWORD']
        django.setup()
        return super(WSGIEnvironment, self).__call__(environ, start_response)

application = WSGIEnvironment()

Upvotes: 1

Views: 1153

Answers (1)

Graham Dumpleton
Graham Dumpleton

Reputation: 58563

SetEnv does not set process wide environment variables for a WSGI application, it sets the per request WSGI environ variables passed in the environ dictionary to the WSGI application with the request. That WSGI application entry point is called after Django has been initialised though, so setting os.environ with that at that point is too late. It is also regarded as bad practice to update os.environ on a per request basis. Using a separate WSGI script file is better.

# production.wsgi

import os

os.environ['DJANGO_SETTINGS_MODULE'] = '....'
....

from prehranske_oznacbe.wsgi import application

And have WSGIScriptAlias reference production.wsgi file by path.

Upvotes: 3

Related Questions