Tiki
Tiki

Reputation: 1206

Serving a second application from a sub-path of another

I am trying to serve two django projects from the same server using WSGI, but require that one run from example.com/ (let's call that app1) and the other from example.com/foo/ (app2). I tried setting this up with separate daemon processes as described in Graham's comment here, but that appears not to work when one of the paths is a subdirectory of the other. All requests for example.com/foo/... are still being handled by the app1.

Is there any way I can achieve what I'm looking for without needing to combine the two projects into one (which would be a difficult task)?

This is what I currently have in my site configuration:

WSGIDaemonProcess app1 \
    python-path=<path for app1's virtualenv>
WSGIDaemonProcess app2 \
    python-path=<path for app2's virtualenv>
WSGIScriptAlias / <path to app1's wsgi.py>
WSGIScriptAlias /foo/ <path to app2's wsgi.py>

<Location />
WSGIProcessGroup app1
</Location>

<Location /foo/>
WSGIProcessGroup app2
</Location>

Update:

I've tried using LocationMatch instead of Location to try to have every request to a path that doesn't start with /foo delegated to app1 and those that do to app2, but that doesn't work either for some reason. Now, requests to /foo/... result in a 500 error with this line in the error log:

mod_wsgi (pid=12032): Exception occurred processing WSGI script '<app1's wsgi.py>'.

Any ideas?

The bottom of the above has been changed to

<LocationMatch "^/(?!foo.*)">
WSGIProcessGroup app1
</LocationMatch>

<LocationMatch "^/foo.*">
WSGIProcessGroup app2
</LocationMatch>

Update 2:

After looking at the error log further, it looks like the requests to /foo/... are being handled by app1's wsgi.py file, but using the python path for app2, meaning that the correct WSGIProcessGroup directive is being applied. Therefore, the problem appears to be a ScriptAlias collision. Is it possible to have this alias be a regex as well to make sure /foo... is not matched to /?

Upvotes: 2

Views: 783

Answers (2)

Graham Dumpleton
Graham Dumpleton

Reputation: 58523

Use:

WSGIDaemonProcess app1 \
    python-path=<path for app1's virtualenv>
WSGIDaemonProcess app2 \
    python-path=<path for app2's virtualenv>

WSGIScriptAlias /foo <path to app2's wsgi.py>
WSGIScriptAlias / <path to app1's wsgi.py>


WSGIProcessGroup app1

<Location /foo>
WSGIProcessGroup app2
</Location>

The order of the WSGIScriptAlias directives is important. The most deeply nested URL paths must come first.

This particular ordering issue is documented in:

Upvotes: 2

Tiki
Tiki

Reputation: 1206

Regular expressions turned out to be the solution. WSGIScriptAliasMatch is able to match a specific regex for a path instead of just the beginning of the path, which caused a collision because, obviously, both paths begin with /.

For posterity, here's the final configuration:

WSGIDaemonProcess app1 \
    python-path=<path for app1's virtualenv>
WSGIDaemonProcess app2 \
    python-path=<path for app2's virtualenv>
WSGIScriptAliasMatch "^/(?!foo.*)" <path to app1's wsgi.py>
WSGIScriptAlias /foo <path to app2's wsgi.py>

<LocationMatch "^/(?!foo.*)">
WSGIProcessGroup app1
</LocationMatch>

<LocationMatch "^/foo.*">
WSGIProcessGroup app2
</LocationMatch>

Upvotes: -1

Related Questions