Reputation: 53
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
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