djbob2

Well-Known Member
May 14, 2005
99
0
166
That's exactly my current setup :)

I'm having the user that requested this feature test this with his own app, but he's being rather slow and unresponsive. I'm probably just going to find a test app on the 'net to see if my current setup is OK.
 

djbob2

Well-Known Member
May 14, 2005
99
0
166
Hello all!

I've successfully implemented Django under mod_wsgi embedded mode. To get it working, first follow the tutorial shacker23 provided to setup Django and mod_wsgi, and then follow the directions at the bottom of this page to get embedded mode working.

You have permission to copy the files I provide in the tutorial on that last link into your own tutorials, but permission is not granted to copy anything else from that page.
 
Last edited:

shacker23

Well-Known Member
Feb 20, 2005
263
1
168
I also just implemented Django with mod_wsgi on a WHM/cPanel host, starting with mandric's tutorial instructions above. I encountered a few things that weren't covered there, so am posting my personal knowledgebase article here in case anyone finds useful tidbits in it.

Install Pyton 2.5 in a separate location.

I used /opt/python but am told that /opt/local/python is more standard for alternate python installations.

After grabbing source...

Code:
configure --enable-shared --prefix=/opt/python
make install
Environment

Put in root’s ~/.bash_profile:

Code:
alias python='/opt/python/bin/python'
You don’t want to be using $LD_LIBRARY_PATH to make python load its libs. Otherwise you’ll hit problems when installing mod_wsgi . But without LD_LIBRARY_PATH you can’t even launch python. The trick is this:

Code:
cat /etc/ld.so.conf.d/python2.5.conf
/opt/python2.5/lib
then run
Code:
ldconfig
. You can now just run “python” and get python 2.5 (rather than cpanel system 2.4) without library load errors.

Also install setuptools from source:

Code:
sh setuptools-0.6c9-py2.6.egg --prefix=/opt/python
MySQL and sqlite bindings

Compiled these from source and built :

Code:
python setup.py build
python setup.py install
Should now be able to launch python and :

Code:
import sqlite3
import MySQLdb
without errors.

mod_wsgi

Django professionals prefer mod_wsgi over mod_python by a wide margin, and hosts should too - it's less memory intensive, and much faster. We've found it 100% stable in a production Django environment.

It’s important to read the mod_wsgi docs on building with shared libs - mod_wsgi should compile to around 140k. If it comes out 3MBs, then it’s got libraries baked in and will be resource wasteful.

Code:
./configure --with-apxs=/usr/local/apache/bin/apxs \
--with-python=/opt/python/bin/python
creates:

Code:
/usr/local/apache/modules/mod_wsgi.so
In WHM | Apache Setup, in Pre VirtualHost Include, add:

Code:
LoadModule wsgi_module /usr/local/apache/modules/mod_wsgi.so
AddHandler wsgi-script .wsgi
WSGISocketPrefix run/wsgi
Apache should not complain about missing libs. If it does… see section above about environment.

Apache will need a “run” dir to store the .pid files in:

Code:
mkdir -p /usr/local/apache/run
chmod a+w /usr/local/apache/run
Client setup

Each client gets their own django installation - not sharing a system-wide one. This way different users can make their own decisions on whether to use bleeding edge trunk or an older version, etc. Clients are pointed to a public Django FAQ for their part of the setup. Root needs to set up a vhost definition and a wsgi bootstrap script for the domain, after learning the client’s project dir.

Technically the customer could do some of this, but to make it easier to get them bootstrapped, we’ll do most of it for them. If they want to create a project “foobar” on domain.com, do:

Code:
mkdir -p /home/[user]/sites/[domain]
cd /home/[user]/sites/[domain]
svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
ln -s django-trunk/django django
mkdir .python-eggs
chmod 777 .python-eggs
/home/[username]/sites/domain.com/django/bin/django-admin.py startproject foobar
cd /home/[username]
chown -R [username]: sites
Add to the user’s .bash_profile:

Code:
# Use python 2.5
alias python='/opt/python/bin/python'

# Set python path
export PYTHONPATH='$PYTHONPATH:/home/[username]/sites/[domain.com]'
User should now get Python 2.5 when launching Python, and should be able to:

Code:
import MySQLdb
import sqlite3
import django
without errors. Now to set up the vhost and the wsgi bootstrap:
Bootstrap

Create
Code:
/home/[username]/public_html/something.wsgi
:

Code:
#!/opt/python/bin/python
import os, sys
sys.path.insert(0,'/home/[username]/sites/domain.com')
os.environ['DJANGO_SETTINGS_MODULE'] = 'foobar.settings'
os.environ['PYTHON_EGG_CACHE'] = '/home/[username]/sites/domain.com/.python-eggs'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Note: This assumes project name “foobar” created above, or by user.
Set up the vhost

Code:
mkdir -p /usr/local/apache/conf/userdata/std/2/[username]/domain.com
vi /usr/local/apache/conf/userdata/std/2/[username]/domain.com/vhost.conf
Contents:

Code:
<IfModule mod_alias.c>
Alias /robots.txt /home/[username]/sites/domain.com/foobar/media/robots.txt
Alias /site_media /home/[username]/sites/domain.com/foobar/media
Alias /admin_media /home/[username]/sites/domain.com/django/contrib/admin/media
</IfModule>

<IfModule mod_wsgi.c>
# See the link below for an introduction about this mod_wsgi config.
# http://groups.google.com/group/modwsgi/browse_thread/thread/60cb0ec3041ac1bc/2c547b701c4d74aa

WSGIScriptAlias / /home/[username]/public_html/something.wsgi
WSGIDaemonProcess [username] processes=7 threads=1 display-name=%{GROUP}
WSGIProcessGroup [username]
WSGIApplicationGroup %{GLOBAL} 
</IfModule>

# This fixes the broken ErrorDocument directive we inherit that breaks auth
# if we use a WSGI app.
ErrorDocument 401 "Authentication Error"
ErrorDocument 403 "Forbidden"
Now tell main apache conf to start including this vhost definition:

Code:
/scripts/verify_vhost_includes
/scripts/ensure_vhost_includes --user=[username]
User should now be good to go, and domain.com should be serving a Django site. From here on out they’ll be able to restart their django instance with:

Code:
touch ~/public_html/something.wsgi
 

dwh2

Well-Known Member
Jan 14, 2004
106
0
166
I've gotten most of the way through this...it helped a lot to look at:
Setup Python 2.5, mod_wsgi, and Django 1.0 on CentOS 5 (cPanel) | Perplexed Labs

but I got errors on django-admin.py startproject. Figured out I needed to enable the shell as well as switch to the user and try it from their account...which showed better errors. If you don't have permission to created a directory under sites/{domain}/ then startproject won't work. Futz w/ the permissions and eventually you'll get there...

Also, directory structure caused me a problem. Installing to /opt/local/python messed up the sh setuptools command. Reinstalled on /opt/local/python2.6 and it worked perfectly. Anyway much better to install to version numbers, because on upgrade, you will know what you are running, and processes pointing to old versions are much easier to debug.
 

big

Well-Known Member
Aug 12, 2001
224
0
316
Earth
any idea when cPanel will have mod_wsgi with easyapache to make our life easier? :)
 

shacker23

Well-Known Member
Feb 20, 2005
263
1
168
They're still taking votes on the issue. If you have a growing number of users requesting Django support, be sure to vote on the ticket. Dreamhost recently rolled out official Django support and we don't want to lose those users to DH!
 

cPanelDavidG

Technical Product Specialist
Nov 29, 2006
11,212
13
313
Houston, TX
cPanel Access Level
Root Administrator
They're still taking votes on the issue. If you have a growing number of users requesting Django support, be sure to vote on the ticket. Dreamhost recently rolled out official Django support and we don't want to lose those users to DH!
We no longer use Bugzilla for tracking current interest in support for features. Instead, please start a thread in the Feature Requests for cPanel and WHM forum. This will allow for discussion about how you feel such functionality would best be implemented in addition to showing interest for such a feature to be added.

Feel welcome to post a link to that thread from this thread so that discussion can occur independently of this how-to discussion.