1

On a single CentOS server I want to manage multiple Django applications, one per domain, using virtual hosts and virtualenvs (each application has its own virtual environment).

I will present here my configuration, the logs produced and explain what I am expecting (but failing) to see.

I am using mod_wsgi 4.4 and software collections rh-python34 and httpd24.

My virtual hosts are configured like this:

Global configuration

Define RROOT "/opt/rh/httpd24/root"
Define RDOCROOT "/opt/rh/httpd24/root/var/www"

WSGIScriptAlias /wsgi "${RDOCROOT}/wsgi-bin"
WSGIProcessGroup localhost
<Directory "${RDOCROOT}/wsgi-bin">
        Order allow,deny
        Allow from all
</Directory>

With the above config, I would like to take care of the server accessed by IP, e.g. going to 123.123.123.123:80/wsgi/ should run the scripts in RDOCROOT/wsgi-bin. It doesn't work, and actually the request on the IP address is handled by the first virtual host. But this is a side question.

Per virtual-host configuration (DOMAIN.COM changes, e.g. example1.com, example2.com)

<VirtualHost *:80>
        ServerName DOMAIN.COM
        ServerAdmin [email protected]
        DocumentRoot "${RDOCROOT}/DOMAIN.COM/html"
        ErrorLog "${RDOCROOT}/DOMAIN.COM/error.log"
        CustomLog "${RDOCROOT}/DOMAIN.COM/access.log" combined
        <Directory "${RDOCROOT}/DOMAIN.COM/html">
                Options FollowSymLinks
                AllowOverride All
                Require all granted
                <IfModule mod_headers.c>
                        Header set Access-Control-Allow-Origin "http://DOMAIN.COM"
                </IfModule>
        </Directory>
        ScriptAlias /cgi/ "${RDOCROOT}/DOMAIN.COM/cgi-bin/"
        <Directory "${RDOCROOT}/DOMAIN.COM/cgi-bin">
                AllowOverride None
                Options None
                Require all granted
                AddDefaultCharset utf-8
        </Directory>

        WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/wsgi:${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/
        WSGIProcessGroup DOMAIN.COM

        WSGIScriptAlias /wsgi/ "${RDOCROOT}/DOMAIN.COM/wsgi-bin/"
        <Directory "${RDOCROOT}/DOMAIN.COM/wsgi-bin">
                Require all granted
        </Directory>
</VirtualHost>

So, virtual hosts should have the html pages in DOMAIN.COM/, the /cgi-bin/ scripts in DOMAIN.COM/cgi/ and the /wsgi-bin/ scripts in DOMAIN.COM/wsgi/, and all of them work.

The problem is that the virtual env has no effect: packages from that virtual env cannot be loaded. To debug, I set the log level to info and created a test script that just fails printing the site packages directories:

$ cat wsgi-bin/app.py    
import site
raise RuntimeError('Site {} {}'.format(site.getuserbase(), site.getsitepackages()))

When I access DOMAIN.COM/wsgi/app.py, error.log contains the following (without prefixes, timestamps and pids):

mod_wsgi (pid=20267): Attach interpreter ''.
mod_wsgi (pid=20267): Adding '(null)' to path.
mod_wsgi (pid=20267): Adding '/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages/' to path.
mod_wsgi (pid=20267): Create interpreter 'WWW.DOMAIN.COM:80|/wsgi/app.py'.
mod_wsgi (pid=20267): Adding '(null)' to path.
mod_wsgi (pid=20267): Adding '/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages/' to path.
[remote SOMEIP] mod_wsgi (pid=20267, process='WWW.DOMAIN.COM', application='WWW.DOMAIN.COM:80|/wsgi/app.py'): Loading WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py'.
[remote SOMEIP] mod_wsgi (pid=20267): Target WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py' cannot be loaded as Python module.
[remote SOMEIP] mod_wsgi (pid=20267): Exception occurred processing WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py'.
[remote SOMEIP] Traceback (most recent call last):
[remote SOMEIP]   File "/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py", line 5, in <module>
[remote SOMEIP]     raise RuntimeError('Site {} {}'.format(site.getuserbase(), site.getsitepackages()))
[remote SOMEIP] RuntimeError: Site /usr/share/httpd/.local ['/opt/rh/rh-python34/root/usr/lib64/python3.4/site-packages', '/opt/rh/rh-python34/root/usr/lib/python3.4/site-packages', '/opt/rh/rh-python34/root/usr/lib/site-python']

From the third line of the log it seems that the virtualenv is added correctly to the sites, but from the last line, produced by the script, appears that system-wide site-packages are used.

The directories are correct, double-checked.

Where am I failing?

1 Answer 1

2
+50

WSGIPythonHome

For virtualenv installations, you may need to specifically use WSGIPythonHome instead.

WSGIPythonHome ${RDOCROOT}/DOMAIN.COM/django-venv/

Configuring WSGIDaemonProcess with python-path

You may need to change the paths you provide:

WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/wsgi:${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/

to only use one of them (see also release notes for mod_wsgi 4.4.15)

WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/

Recompiling for other python

In some instances, you may need to recompile mod_wsgi for that particular python version in addition to the WSGIPythonHome or python-path tricks.

Configuring site directly in wsgi application

As a last resort, you can configure site packages in the wsgi app.py:

import site
site.addsitedir('/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages')

mod_wsgi known issues with WSGIPythonPath

From the release notes for mod_wsgi 4.4.15:

  1. When specifying multiple directories for the Python module search path using the WSGIPythonPath directive, or the python-path option to WSGIDaemonProcess, it was failing under Python 3 due to incorrect logging. It was therefore only possible to add a single directory.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the feedback! My mod_wsgi is already compiled for python3, I will try with the WSGIPythonHome, although from the doc I read that "For mod_wsgi 2.4 onwards this is not an issue and a virtual environments site-packages will always override that in standard Python installation." - I am using version 4.4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.