1

We're looking for a clean and isolated way to host several Django sites on a single Apache with vhosts on Ubuntu 14.04.

Following the docs https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/modwsgi/#using-mod-wsgi-daemon-mode and Where should WSGIPythonPath point in my virtualenv? , we set the following setup :

Have a global virtualenv for mod_wsgi

virtualenv -p /usr/bin/python3 /home/admin/vhosts_venv
. vhosts_venv/bin/activate
pip install mod-wsgi

sudo /home/admin/vhosts_venv/bin/mod_wsgi-express install-module
sudo vi /etc/apache2/mods-available/wsgi_express.load

added :

LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi-py34.cpython-34m.so

Then have a vhost venv and a basic app :

virtualenv -p /usr/bin/python3 /home/admin/vhost1_venv
. vhost1_venv/bin/activate
pip install Django
pip install PyMySQL

django-admin startproject vhost1
cd vhost1
python manage.py startapp main

Setup host resolution with :

sudo vi /etc/hosts

updated :

127.0.0.1       localhost vhost1.example.com

Setup Apache vhost with :

<VirtualHost vhost1.example.com:80>
  ServerName vhost1.example.com
  ServerAlias example.com
  ServerAdmin webmaster@localhost
  #DocumentRoot /var/www/html

  ErrorLog ${APACHE_LOG_DIR}/vhost1_error.log
  CustomLog ${APACHE_LOG_DIR}/vhost1_access.log combined

  WSGIProcessGroup  vhost1.example.com
  WSGIScriptAlias / /home/admin/vhost1/vhost1/wsgi.py process-group=vhost1.example.com
  WSGIDaemonProcess vhost1.example.com user=www-data group=www-data threads=25 python-path=/home/admin/vhost1:/home/admin/vhost1_venv/lib/python3.4/site-packages:/home/admin/vhosts_venv/lib/python3.4/site-packages

  <Directory /home/admin/vhost1>
    <Files wsgi.py>
      <IfVersion < 2.3>
        Order deny,allow
        Allow from all
      </IfVersion>
      <IfVersion >= 2.3>
        Require all granted
      </IfVersion>
    </Files>
  </Directory>

</VirtualHost>

Enabled everything with :

sudo a2enmod wsgi_express
sudo a2ensite vhost1
sudo service apache2 restart

When testing it, we get 2 answers for a single curl request, delivered in 2 timing (sometime like 0.5s between each) :

curl vhost1.example.com

It worked! Congratulations on your first Django-powered page.

Of course, you haven't actually done any work yet. Next, start your first app by running python manage.py startapp [app_label].

You're seeing this message because you have DEBUG = True in your Django settings file and you haven't configured any URLs. Get to work!

Directly followed by :

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at webmaster@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log. Apache/2.4.7 (Ubuntu) Server at vhost1.example.com Port 80

In /var/log/apache2/error.log, we get :

[Mon Aug 15 15:37:42.754139 2016] [core:notice] [pid 18622:tid 140151787534208] AH00051: child pid 18717 exit signal Segmentation fault (11) , possible coredump in /etc/apache2

and in /var/log/apache2/vhost1_access.log :

127.0.0.1 - - [15/Aug/2016:15:37:42 +0200] "GET / HTTP/1.1" 500 2593 "-" "curl/7.35.0"

How to set it up correctly?

Community
  • 1
  • 1
samb
  • 1,713
  • 4
  • 22
  • 31
  • 3
    If you are using mod_wsgi 4.5.4, remove it and install 4.5.3 instead. An issue affecting Python 3 got introduced in 4.5.4 which causes processes to crash if application sends anything to stdout/stderr using ``print`` or Python logging module. There will be a 4.5.5 release today which rolls back the change while solution is found. – Graham Dumpleton Aug 15 '16 at 23:52
  • 1
    Another source of crashes is C extensions which don't work in sub interpreters. Use ``application-group=%{GLOBAL}`` option with ``WSGIScriptAlias``. You also don't need the ``WSGIProcessGroup`` directive as you are using the ``process-group`` option to ``WSGIScriptAlias``. – Graham Dumpleton Aug 16 '16 at 02:02
  • 1
    The tracking of Python virtual environment ``site-packages`` directories is also suspect. Should only refer to one and preferable to use ``python-home`` option to denote top of virtual environment and not use ``python-path`` to ``site-packages`` directory in it. – Graham Dumpleton Aug 16 '16 at 02:04
  • Wow ... upgrading from 4.5.4 to 4.5.5 fixed it. – samb Aug 16 '16 at 06:55
  • For the 2nd comment : When removing WSGIProcessGroup and setting `WSGIScriptAlias / /home/admin/vhost1/vhost1/wsgi.py process-group=vhost1.example.com application-group=%{GLOBAL}` , I get the error while restarting Apache2 : `WSGI process group not yet configured.`. Is this what you meant? – samb Aug 16 '16 at 07:04
  • Regarding 3rd comment, we need 2 venv for a shared hosting. One has the mod-wsgi (shared for every hosted sites). The second has the site's packages. I'm not sure to understand the syntax you mean. Could you write it down please? Thanks – samb Aug 16 '16 at 07:07
  • 2
    Move the ``WSGIDaemonProcess`` directive before the ``WSGIScriptAlias`` directive. As to your virtual environments, what you are describing doesn't make sense. So long as the per site virtual environment was created off the same Python installation mod_wsgi was built for, that is enough. You do not need to also reference the Python installation mod_wsgi was built against. Suggest you use the mod_wsgi mailing list if need more explanation. – Graham Dumpleton Aug 16 '16 at 07:55
  • 2
    Also read http://blog.dscpl.com.au/2009/11/save-on-memory-with-modwsgi-30.html and make sure you are turning off embedded mode if always delegating to daemon process mode. – Graham Dumpleton Aug 16 '16 at 07:56
  • Thanks for your explanations. I've understand both the no need to add the `vhosts_venv` and the need to add `WSGIRestrictEmbedded On`. Things work smooth now. If you'd like to write an "answer" ... I'd happy to mark it as "accepted". Regards. – samb Aug 16 '16 at 08:48

1 Answers1

0

To summarize Graham Dumpleton's answer

  • mod_wsgi 4.5.4 was broken with Python3. 4.5.5 fixed it.
  • It's possible to setup a Python virtualenv for the virtualhosting (with package mod_wsgi) but is recommended to setup a Python virtualenv using python-home option and not python-path.
  • It's recommended to set WSGIRestrictEmbedded On according to http://blog.dscpl.com.au/2009/11/save-on-memory-with-modwsgi-30.html

/etc/apache2/mods-available/wsgi_express.conf looks like :

WSGIRestrictEmbedded On

/etc/apache2/sites-available/vhost1.conf looks like :

<VirtualHost vhost1.example.com:80>
  ServerName vhost1.example.com
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html

  ErrorLog ${APACHE_LOG_DIR}/vhost1_error.log
  CustomLog ${APACHE_LOG_DIR}/vhost1_access.log combined

  WSGIDaemonProcess vhost1.example.com threads=15 python-home=/home/admin/vhost1_venv python-path=/home/admin/vhost1
  WSGIScriptAlias / /home/admin/vhost1/vhost1/wsgi.py process-group=vhost1.example.com application-group=%{GLOBAL}

  <Directory /home/admin/vhost1>
    <Files wsgi.py>
      <IfVersion < 2.3>
        Order deny,allow
        Allow from all
      </IfVersion>
      <IfVersion >= 2.3>
        Require all granted
      </IfVersion>
    </Files>
  </Directory>

</VirtualHost>
Graham Dumpleton
  • 57,726
  • 6
  • 119
  • 134
samb
  • 1,713
  • 4
  • 22
  • 31