I'm trying to set up Apache, Django and mod_xsendfile to allow me to control access to certain files using Django authentication while still using Apache to send the actual file data.

I have a problem with this configuration:

# Some files must be publicly available without the Django auth check.
# When I comment this out, public media is not accessible but the WSGI script for
# /media/attachment DOES get called.
# So I think I need to somehow exclude /media/attachment from the effect of this Alias

Alias /media/ /var/www/vhosts/domain.com/subdomains/project/httpdocs/media/

# This <Location> block disables everything (Forbidden) regardless of the WSGI stuff
#<Location /media/attachments>
#    Deny from all

WSGIScriptAlias / /var/www/vhosts/cdomain.com/subdomains/project/httpdocs/web/apache/django.wsgi
WSGIScriptAlias /media/attachments /var/www/vhosts/domain.com/subdomains/project/httpdocs/web/apache/django.wsgi

XSendFile On

How can I tell Apache to route requests to /media/attachments through the WSGI scripts and serve the rest of /media directly?


The Alias directive takes precedence over WSGIScriptAlias, so you cannot mount WSGI application under a URL specified by Alias directive.

As is, you would also have had an issue here with multiple instances of Django being started up in each process, due to multiple WSGIScriptAlias directives, unless you have used WSGIApplicationGroup directive to force them to be delegated to the same Python sub interpreter within the processes.

As to a solution, it is a bit tricky to do what you want because of the layout you are using. I have an idea, but would need to test it out first.


First possibility is that if you have everything in traditional sub directories of 'css', 'img' and 'js' as used by Django, instead of the Alias directive above, use:

AliasMatch ^/(css|img|js)(/.*)$ /var/www/vhosts/domain.com/subdomains/project/httpdocs/media/$1$2

and delete:

WSGIScriptAlias /media/attachments /var/www/vhosts/domain.com/subdomains/project/httpdocs/web/apache/django.wsgi

This should mean that only the static files in those subdirectories will match the Alias directive and be served directly.


The other option, which I had to test, is to not use WSGIScriptAlias, but use Alias directive for everything. This would be done like:

Alias /media/attachments/ /var/www/vhosts/domain.com/subdomains/project/httpdocs/web/apache/django.wsgi
Alias /media/ /usr/local/django/example/media/
Alias / /var/www/vhosts/domain.com/subdomains/project/httpdocs/web/apache/django.wsgi

<Directory /var/www/vhosts/domain.com/subdomains/project/httpdocs/web/apache>
WSGIApplicationGroup %{GLOBAL}
AddHandler wsgi-script .wsgi
Options ExecCGI
Order allow,deny
Allow from all

Because Alias directive alone is used, all evaluated at same precedence level. You just need to ensure that more deeply nested URLs come first.

Instead of WSGIScriptAlias, we use AddHandler to map .wsgi file as a WSGI script file, and set ExecCGI option so mod_wsgi will allow it to be used as WSGI script file.

We set WSGIApplicationGroup just to make sure only one Django instance is created in each process. The value of %{GLOBAL} makes it use main Python interpreter.

So, two options depending on your fancy.

  • That is brilliant. I'm going to go with #1 but will keep #2 in mind for a more complicated site in which the AliasMatch wouldn't be enough. Thanks! – Tomas Andrle Aug 29 '09 at 16:30
  • 2
    Most important information for me was "Alias directive takes precedence over WSGIScriptAlias". This enables for a very flexible mixing of static files and Django application in the same url space. – geekQ Sep 11 '11 at 14:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.