Multiple mod_wsgi apps on one virtual host directing to wrong app

Question:

I’m trying to get two (or more) Django applications set up at subdirectories under the same domain, e.g.:

http://example.com/site1/
http://example.com/site2/

I know that normally this works fine by setting up an apache virtualhost like this:

<VirtualHost *:80>
    ...
    WSGIScriptAlias /site1 /path/to/site1.wsgi
    WSGIScriptAlias /site2 /path/to/site2.wsgi
</VirtualHost>

Now, I’ve verified that each site works individually. But when I try to run both side-by-side, apache sends me to whichever site the worker process loaded first. Example:

  1. Restart apache configured to serve 6 threads
  2. Load example.com/site1/, get the correct page
  3. Load example.com/site2/, get the correct page
  4. Repeat 2 and 3 2 more times.
  5. Refresh example.com/site1/ repeatedly, watch it cycle from site to site.

Effectively, for any given number of worker processes, it cycles through the total number of them sending the request to whichever one it hit first regardless of the WSGIScriptAlias directive. No matter what I do (setting WSGIProcessGroup, daemon mode vs. embedded mode, or directives) it continues to exhibit this behavior.

If anyone can point out what I’m doing wrong here, that would be phenomenal!

Asked By: Gabriel Hurley

||

Answers:

I’ve had trouble with this myself. Instead of trying to get the Apache configuration right, I decided instead to use a single WSGIScriptAlias and have WSGI middleware which routed requests to the correct applications. My code is at https://github.com/zhemao/flotilla. I haven’t tested it that much, so use it with caution, but I hope it helps.

Answered By: Zhehao Mao

I’ve had multiple WSGI apps running on a single Apache install, and found that the easiest thing to do is just have multiple process groups– one for each of the apps.

One downside, versus actually trying to get a single process to run both (or more) apps, is that this might use a little more resident memory than you could get away with otherwise. But it keeps them pretty well separated and avoids hassle. And that might not be a concern for you (it wasn’t for me).

(It might not be that bad either, they might be able to share a lot of text pages? That’s just idle speculation; I haven’t verified this in any way, as my setup was not at all memory-starved)

Here’s some snippets of my httpd.conf, approximately:

WSGIDaemonProcess khdx_wsgi user=galdosd group=galdosd maximum-requests=10000
WSGIScriptAlias /khdx /home/galdosd/khdxweb/rel/khdx/apache/django.wsgi
<Location /khdx>
WSGIProcessGroup khdx_wsgi
</Location>

WSGIDaemonProcess sauron_wsgi user=galdosd group=galdosd maximum-requests=10000
WSGIScriptAlias /sauron /home/galdosd/finalsauronweb/django-root/apache/django.wsgi
<Location /sauron>
WSGIProcessGroup sauron_wsgi
</Location>
Answered By: Domingo Ignacio

Domingo Ignacio’s answer set me on the right track. I’d like to point out an important fact about making it work: The two process groups must be within the same VirtualHost. (This is based on my tests with Ubuntu 12.04.3 LTS, Apache 2.2.22 and a couple of WSGI apps written in Python.)

For example, this did not work for me, resulting in the ability to access app1 but a 404 error for app2:

<VirtualHost *>
        WSGIDaemonProcess app1 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app1 /app1/app1.wsgi

        <Location /app1>
                WSGIProcessGroup app1
        </Location>
</VirtualHost>

<VirtualHost *>
        WSGIDaemonProcess app2 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app2 /app2/app2.wsgi

        <Location /app2>
                WSGIProcessGroup app2
        </Location>
</VirtualHost>

Removing the middle and tags, so as to have a single VirtualHost, solved the problem:

<VirtualHost *>
        WSGIDaemonProcess app1 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app1 /app1/app1.wsgi

        <Location /app1>
                WSGIProcessGroup app1
        </Location>

        WSGIDaemonProcess app2 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app2 /app2/app2.wsgi

        <Location /app2>
                WSGIProcessGroup app2
        </Location>
</VirtualHost>
Answered By: Steve Saporta

Anyone know how to get this to work with one of the applications at the root?

This is what I’m currently trying. app2 on the root serves find but I’m getting a 400 bad request: "The browser (or proxy) sent a request that this server could not understand" on app1.

<VirtualHost *>
    WSGIDaemonProcess app1 user=someuser group=somegroup threads=5
    WSGIScriptAlias /app1 /app1/app1.wsgi

    <Location /app1>
            WSGIProcessGroup app1
    </Location>

    WSGIDaemonProcess app2 user=someuser group=somegroup threads=5
    WSGIScriptAlias / /app2/app2.wsgi

    <Location / >
            WSGIProcessGroup app2
    </Location>
Answered By: Roger Lew