Recently I purchased a new Dedicated server box running Ubuntu 8.10 / DirectAdmin and needed to transfer a bunch of my stuff to it. One of the sites I needed to trandsfer was CVGM ( http://www.cvgm.net ) which is powered by Django / Python / Mod_WSGI. I couldn’t find many instructions on the net on how to complete the task easily, so after I figured out how to do it, I wanted to post my results here so that other people who need the same kind of help can find the post and maybe use it 🙂
The DirectAdmin default setup uses a customized version of Apache in order to work, and as a result, it’s not as simple to work with/customize as a regular install of apache. To give you an example, if you would apt-get a module (such as mod_wsgi) that relies on apache2 as a dependency, it thinks apache2 isn’t even installed, so be careful! The global config file for the DirectAdmin apache is /etc/httpd/conf/httpd.conf and I should point out that right now, you should not edit anything in this file whatsoever!!
First, we need to install the Apache module for Mod WSGI. I copied a version of the file from a copy of 8.10 Server I installed on a VM to make sure it matched the same system requirements (Python 2.5) however you can always build one, or obtain one from somewhere on the net. Once I built the file, I copied it to /usr/lib/apache/mod_wsgi.so on the dedicated box.
There are two ways that you can proceed to activate the module, and i’ll explain both ways. The 1st way is probbably more beneficial if you plan on running multiple WSGI applications, whereas the second is better if you just plan on running a single site and you don’t want to initialize it for every thread your apache creates.
Enabling As Global Module
This is the simplest method of enabling the module. Open the following file for editing:
There should already be a line in there for PHP, so we only need to add the following line underneath it:
LoadModule wsgi_module /usr/lib/apache/mod_wsgi.so
Save and Exit the file, if you restart the httpd instances within DirectAdmin, they will all have access to mod_wsgi features.
Setting up a VirtualHost to run a WSGI Application
I’d like to point out here that we are manually editing/changing the automated VirtualHost information generated from within DirectAdmin, so DirectAdmin might change it all back again if you go to edit anything through the admin panels. Remember, when it works, back it up in case that does happen!
The VirtualHost lists are defined in a user’s httpd.conf file, so to edit the list for your site, run the following command:
vim /usr/local/directadmin/data/users/[UserName]/httpd.conf (Replacing UserName with the user account name set up under your site)
Modify the top portion of your Vhost file to look like the following, with your own WSGI settings of course:
# Frontpage requires these parameters in every httpd.conf file or else # it won't work. ServerRoot /etc/httpd WSGIDaemonProcess ProcessName threads=25 WSGIProcessGroup ProcessName <VirtualHost *:80> ...
Inside the VirtualHost container, you will add your actual WSGI code as such:
# Load the WSGI adapter just for this VirtualHost, if you choose not to enable it # Globally. Do not add this line if you added the module globally!! LoadModule wsgi_module /usr/lib/apache/mod_wsgi.so # Set up Aliases to Django admin, and our own static files Alias /media/ /usr/share/python-support/python-django/django/contrib/admin/media/ (path might vary on your setup) Alias /static/ /path/to/static/ <Directory /usr/share/python-support/python-django/django/contrib/admin/media> (path might vary on your setup) Order deny,allow Allow from all </Directory> # Direct root to our WSGI script file WSGIScriptAlias / /path/to/file.wsgi <Directory /path/to> Order deny,allow Allow from all </Directory> <Directory /path/to/static> Order deny,allow Allow from all </Directory>
Save the changes to your VirtualHost. I would like to point out here, that for CVGM I chose to comment out completely the same VirtualHost entry for SSL (port 443). My site has no use for SSL, and duplicating this code in the 2nd VirtualHost (which is what would happen if edit the Custom HTTPD for this domain in DirectAdmin) will cause an error for already having being called once.
The WSGI file for your project is created in pretty much the standard way:
import os, sys sys.path.append('/path/to') sys.path.append('/path/to/ExtraPath') os.environ['DJANGO_SETTINGS_MODULE'] = 'ProcessName.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
Save it, double check the paths to the files and then restart httpd in DirectAdmin. If all goes well, the site should fire right up! If you start getting 503/500 errors, check the error.log file in the DirectAdmin viewer for a detailed description of what is happening. If there are no errors in the log, it’s not WSGI causing the problem, it’s something else in your code.
Common Error With Mod_WSGI and DirectAdmin
Depending on which version of DirectAdmin you are using, you may run into a massive slap-in-the-face 503 error regarding misconfiguration, and the error log will tell you something like: “No such file or directory: mod_wsgi (pid=7295): Unable to connect to WSGI daemon process”.
If you do run into this problem, you can try one of two things in the virtual host file. Here is a quote directly from Graham Dumpleton on the WSGI homepage explaining the problem and the solution ( http://code.google.com/p/modwsgi/wiki/ConfigurationIssues#Location_Of_UNIX_Sockets ) :
“To resolve the problem, the WSGISocketPrefix directive should be defined to point at an alternate location. The value may be a location relative to the Apache root directory, or an absolute path.
On systems which restrict access to the standard Apache runtime directory, they normally provide an alternate directory for placing sockets and lock files used by Apache modules. This directory is usually called ‘run’ and to make use of this directory the WSGISocketPrefix directive would be set as follows:
Although this may be present, do be aware that some Linux distributions, notably RedHat, also locks down the permissions of this directory as well so not readable to processes running as a non root user. In this situation you will be forced to use the operating system level ‘/var/run’ directory rather than the HTTP specific directory.
Note, do not put the sockets in the system temporary working directory. That is, do not go making the prefix ‘/tmp/wsgi’. The directory should be one that is only writable by ‘root’ user, or if not starting Apache as ‘root’, the user that Apache is started as. ”
So, you would change the top of the VirtualHost to read something along the lines of:
WSGISocketPrefix /var/run/wsgi WSGIDaemonProcess ProcessName threads=25 WSGIProcessGroup ProcessName
After restarting Httpd in DirectAdmin, it should clear up the problem!
This was a post I had originally made a long time ago (November 2009), so I have edited/replaced it here for completeness, as I get a lot email requests about it. I don’t use this setup any longer, and use a dedicated box for CVGM which solved a lot of other issues that I was having at the time, and of course the dedicated box is running a much newer Ubuntu distribution. Thanks!
I have been putting off the inevitable the last couple of weeks, which was the task of converting the database for CVGM.net to UTF8 from the default collation of latin1-swedish-ci. I am not the best when it comes to administering MySQL via command script, and phpMyAdmin didnt do the job properly of conversion for me. After a bit of googling, I found a bash script at islandlinux that was able to help me out considerably:
#!/bin/bash DATABASE=$1 if [ ! "$DATABASE" ]; then echo "Please specify a database" exit fi BACKUPDIR="/root/tmp/mysql_backups/" if [ ! -d "$BACKUPDIR" ]; then mkdir -p "$BACKUPDIR" fi BACKUP="$BACKUPDIR""$DATABASE.sql" mysqldump --add-drop-table --extended-insert "$DATABASE" > "$BACKUP" TABLES=`mysql --batch --execute 'SHOW TABLES' "$DATABASE" | grep -v "^Tables_in"` for TABLE in $TABLES; do echo 'ALTER TABLE `'"$TABLE"'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;'; # uncomment the following line to process the commands #mysql --execute 'ALTER TABLE `'"$TABLE"'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' "$DATABASE" done
This script converted the database tables and everything under it to the correct format. It also backs up the databases first in case something decides to take a crap on you. The problem I had with phpMyAdmin was even though I changed the collation to utf8_general_ci it didn’t do it recursively into the tables and the fields underneath it.
Thanks for the script guys 🙂 You saved me even more work!
Well, after receiving a shit load of spam for a while, and repeated failed attempts to get the site to cron properly (resulting in some tickets taking days to notify me they arrived) I have finally broken down and done the upgrade. This new upgrade also allows CAPTCHA support.
Must admit, it went very smoothly and no problems were encountered. Should anyone need to contact us, you can use http://www.f1-software.com/osticket/ which also has a working 5-min cron job \o/