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 webmaster@DOMAIN.COM
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?