Recently I took the opportunity to configure my server for per-user hosting (to offer some free hosting to people who needed it). Doing this I had to configure mod_wsgi per-user as well. First, let me say that the documentation is excellent, but real world examples are always very helpful. Below is the output of a script which runs per-user on my server.
/etc/apache2/users/username.conf
<VirtualHost *>
ServerAdmin username@localhost
ServerName userdomain.com
ServerAlias userdomain.com www.userdomain.com
WSGIScriptAlias / "/home/username/.wsgi/project_name"
WSGIDaemonProcess userdomain user=username threads=15 display-name=%{GROUP}
WSGIProcessGroup userdomain
DocumentRoot "/home/username/project_name"
Alias /media/ "/home/username/project_name/media/"
<Directory "/home/username/project_name/media">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
Alias /admin-media/ "/usr/local/django-dev/django/contrib/admin/media/"
<Directory "/usr/local/django-dev/django/contrib/admin/media">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
<Directory "/home/username/project_name/">
Options +ExecCGI
Allow from all
</Directory>
ErrorLog /home/username/logs/userdomain.com/error.log
CustomLog /home/username/logs/userdomain.com/access.log combined
</VirtualHost>
/home/username/.wsgi/project_name
import os, sys # Add the project to the python path sys.path.append('/usr/local/django-dev/django') sys.path.append('/home/username') # Set our settings module os.environ['DJANGO_SETTINGS_MODULE']='project_name.settings' import django.core.handlers.wsgi # Run WSGI handler for the application application = django.core.handlers.wsgi.WSGIHandler()

6 Responses to "Setup mod_wsgi for Django and Shared Hosting"
[...] Apache 2.x + mod_wsgiYou can see my configuration example. [...]
It is best not to include ‘processes=1′ option to WSGIDaemonProcess but let it apply its default of 1. This is because there is a subtle little difference between each. When it defaults to 1, wsgi.multiprocess is False, where as setting ‘processes=1′ results in wsgi.multiprocess is True. This distinction exists for where one may use a means of mapping across multiple process groups in same server, or requests are handled across multiple servers in a cluster. In other words, one needs a way of saying the application is logically hosted in a multiprocess setup even though only one process in that particular process group. I know it may be a bit non obvious, but best I could could up with at the time.
Where does this matter? It matters if you want to use an in browser application debugger such as Paste EvalException or the one from Werkzeug. This will not work in a multiprocess setup as it relies on requests going back to the same process. In your setup the requests will go back to the same process, but debuggers such as EvalException think it is multiprocess setup and will not allow you to run it.
So check out the ConfigurationDirectives document on mod_wsgi wiki as well as the DebuggingTechniques document.
BTW, you might also look at the display-name option for WSGIDaemonProcess for mod_wsgi 2.0. Use that and ‘ps’ can be used to distinguish each users processes rather than them all appearing as being named ‘httpd’. Finally, you might also look at VirtualEnvironments document on wiki and setup things so that each user is working out of a Python virtual environment constructed using ‘virtualenv’. That way it is a lot easier for them to install their own Python packages.
Thanks for the reply Graham. I’ll be changing the process count and the process name for sure
I use a combination of mod_wsgi and mod_vhost_alias to reduce apache config changes to a minimum for each new site.
Per-site configuration (except for WSGIDaemonProcess directives) are written in a .htaccess file.
I’ve documented the setup here (in german, but the listings should be readable) http://django-hosting.de/wiki/ApacheModWsgi/
Arne, sounds like your method would work great for hosting multiple projects under the same domain.
dude, you rock. good info. had some problem with the admin media but turned out to be a permissions error.
Leave A Reply