Multiple mod_wsgi apps on one virtual host directing to wrong app
Solution 1
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>
Solution 2
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>
Solution 3
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.
Related videos on Youtube
Gabriel Hurley
I'm an engineer and an artist. I build clouds and cloud-native applications. I'm an expert in Python, JavaScript, and mixology. I believe firmly in open source. My bag of tricks also contains film, photography, graphic design, and audio production. I've been the Project Technical Lead for the OpenStack Dashboard project (Horizon) and a Core Committer for Django (Python web framework). I've worked in startups, enterprises and government agencies. I'm interested in building products that will help shape the world and be used by millions of people.
Updated on July 13, 2022Comments
-
Gabriel Hurley almost 2 years
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:
- Restart apache configured to serve 6 threads
- Load example.com/site1/, get the correct page
- Load example.com/site2/, get the correct page
- Repeat 2 and 3 2 more times.
- 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!
-
Graham Dumpleton almost 13 yearsWhat do you get when you replace the WSGI script files with that described in 'code.google.com/p/modwsgi/wiki/…'?
-
Graham Dumpleton almost 13 yearsUse of maximum-requests is discouraged for production sites unless you really have a crippling memory leak you can't fix straight away.
-
Graham Dumpleton almost 13 yearsYou can't do that with two distinct Django sites because of Django's reliance on single DJANGO_SETTINGS_MODULE environment variable, the value which cannot be changed from one request to the next.
-
Gabriel Hurley almost 13 yearsBrilliant! The separate process groups defined inside the Location blocks worked. My only regret is that I didn't ask here sooner ;-)
-
Domingo Ignacio almost 13 yearsThanks, Graham! Is that because of the occasional restart delay?
-
Graham Dumpleton almost 13 years@Domingo. Yes, because of startup cost and the delay it causes on subsequent requests.
-
Graham Dumpleton almost 13 years@Gabriel. The best place to ask is the actual mod_wsgi mailing list. I don't always read StackOverflow regularly. The use of separate daemon process groups shouldn't strictly be necessary but too busy to investigate original problem right now and on StackOverflow is the worst place to debug such problems anyway, thus why suggest mailing list.
-
Gabriel Hurley almost 13 years@Graham -- thanks for the advice. I keep an eye on that list, actually, but figured I'd ask here first in case it was something obvious before escalating to there. I agree it shouldn't be required (and hasn't been required on other projects) but thankfully this worked and life can go on until we all have more time! ;-)
-
Timmmm over 11 yearsSadly it didn't work for me, possibly because my
WSGIScriptAlias
es are/
and/foo
. Any way around that? -
Domingo Ignacio over 11 years"Don't Do that Then" :-) ... Sounds like you wish Apache would use the /foo handler whenever it... "matches" something, but use the / handler in other cases. That's not how it works. No mechanism for dynamically coming back to Apache and saying "Never mind I can't handle this request after all, let someone else try". The / handler will get everything and /foo will never have a chance. Maybe you can have /foo and /bar and have some redirects within / to /bar or some similar solution. (Note that by doing this, your set of redirects is acting as the explicit definition of the boundaries)
-
LondonAppDev about 10 yearsAny way to get it to work with alias's / and /foo ? It works perfectly with /foo /bar but not with / and /foo...
-
Domingo Ignacio almost 10 years@MarkWinterbottom - read the comment right above your question ;-) (Timmmm asked the same thing... or I have a time machine)
-
rszalski almost 8 years@MarkWinterbottom I know I'm late to the party, but had the same issue. See if this helps: stackoverflow.com/a/23568825/211153
-
edvin almost 4 yearsWhat about If we have two configuration files with one Virtual Host inside of them. Can they work?
-
lukover over 3 yearsYou need to specifically set the process-group for your Aliases (see docs). Set
WSGIScriptAlias /app1 /app1/app1.wsgi process-group=app1
andWSGIScriptAlias / /app2/app2.wsgi process-group=app2
, then it should work. -
Juha Tuomala over 2 years@Timmmm both / and /foo works if you put that "more precise path" first. /foo first and last plain root /. It works like ip-addresses and routing table, more detailed route wins.