Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django + mod_wsgi. Set OS environment variable from Apache's SetEnv

I need to split Django's development and production settings. I decided that if USKOVTASK_PROD variable is set, then app should use production settings. I read this article and tried to do it.

My snippets:

/etc/apache2/sites-enabled/uskovtask.conf:

<VirtualHost *:80>

ServerName uskovtask.*.com
ServerAlias uskovtask.*.com
DocumentRoot /mnt/ebs/uskovtask


Alias /static /mnt/ebs/uskovtask/static/
<Directory /mnt/ebs/uskovtask/static>
    Require all granted
</Directory>

#WSGIPythonPath /mnt/ebs/uskovtask
WSGIDaemonProcess uskovtask.*.com python-path=/mnt/ebs/uskovtask:/usr/lib/python2.7/site-packages
WSGIProcessGroup uskovtask.*.com
WSGIScriptAlias / /mnt/ebs/uskovtask/uskovtask/wsgi.py
SetEnv USKOVTASK_PROD 1


<Directory /mnt/ebs/uskovtask/uskovtask>
<Files wsgi.py>
    Require all granted
</Files>
</Directory>

</VirtualHost>

wsgi.py:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "uskovtask.settings")

from django.core.wsgi import get_wsgi_application

_application = get_wsgi_application()

def application(environ, start_response):
    if 'USKOVTASK_PROD' in environ:
        os.environ.setdefault('USKOVTASK_PROD', environ['USKOVTASK_PROD'])
    return _application(environ, start_response)

settings.py's part:

import os

if 'USKOVTASK_PROD' in os.environ:
    from settings_prod import *
else:
    from settings_dev import *

But it always imports settings_dev's settings. Why?

like image 541
michaeluskov Avatar asked Nov 17 '14 18:11

michaeluskov


People also ask

How to set environment variables for Apache/mod_wsgi hosted Python application?

Setting environment variables for Apache/mod_wsgi hosted Python application. Django documentation says to use: To set environment variables which would be inherited by the Django application referred to by this, one can set them in the envvars file created as part of the Apache installation.

How to set environment variables in Django with Apache?

To set environment variables which would be inherited by the Django application referred to by this, one can set them in the envvars file created as part of the Apache installation.

How to create a separate WSGI script file in Django?

The much simpler way is to create a separate WSGI script file independent of the wsgi.py that Django generates with its startproject template. You might call this django.wsgi, or you might have separate production.wsgi and development.wsgi files if have multiple environments. Place the WSGI script file in the same directory as the wsgi.py file.

Can I set Lang and LC_ALL in mod_wsgi?

This method can be used for any environment variables with the exception of those which affect the operation of the processes as a whole at a system level. That is, you cannot set LANG and LC_ALL in this way. Modern versions of mod_wsgi though have lang and locale options on WSGIDaemonProcess directive which achieve the same result.


2 Answers

I solved this problem by changing wsgi.py to this:

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

class WSGIEnvironment(WSGIHandler):

    def __call__(self, environ, start_response):

        os.environ['USKOVTASK_PROD'] = environ['USKOVTASK_PROD']
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "uskovtask.settings")
        django.setup()
        return super(WSGIEnvironment, self).__call__(environ, start_response)

application = WSGIEnvironment()
like image 103
michaeluskov Avatar answered Oct 26 '22 01:10

michaeluskov


This is related to question Access Apache SetEnv variable from Django wsgi.py file

You need to inherit WSGIHandler as the answer says.

As Graham Dumpleton explains in the second answer,

That all said, the blog post you mention will not usually help. This is because it is using the nasty trick of setting the process environment variables on each request based on the per request WSGI environ settings set using SetEnv in Apache. This can cause various issues in a multi threading configuration if the values of the environment variables can differ based on URL context. For the case of Django, it isn't helpful because the Django settings module would normally be imported before any requests had been handled, which means that the environment variables would not be available at the time required.

and I think this is what is happening in your case.

like image 22
iamkhush Avatar answered Oct 26 '22 01:10

iamkhush