Setting Up WSGI on an Ubuntu Rackspace Cloud Server

February 6th, 2010 by derek

In a previous post I wrote about how to set up mod_python on a Rackspace cloud server running a clean version of Ubuntu 9.04 Jaunty.  This is fine for simple apps, but there are a number of downsides to using mod_python.  Here we will install mod_wsgi, which is a much better solution and nearly as simple.

Warning: I am not an apache expert. This is the result of figuring out for the first time how to set up an apache server from scratch. Please drop a comment if you know of any way to ease the process or have any corrections.

Installing Apache2 and mod_wsgi

First we are going to install apache2.  If you’ve already done this, you can skip this step.

sudo aptitude install apache2 apache2.2-common apache2-mpm-prefork apache2-utils libexpat1 ssl-cert

Next we’ll install WSGI. This should automatically install and enable WSGI on your server by putting wsgi.conf and wsgi.load in /etc/apache2/mods-available and symlinking them to /etc/apache2/mods-enabled.

sudo aptitude install libapache2-mod-wsgi

Configuring the virtual hosts

Next we’re going to set up an apache2 virtual host. This is the file that defines what folders to server up, with what mods, and on what port. We are going to edit the host that is already there, so if you have some configuration existing, you might want to back it up in case it screws around with it.

We’ll be making two folders: one for static files (like HTML) and another for your WSGI (python) scripts.  This is important so that you never accidently serve your raw python files to users.  Allowing the users to see your raw web server code is bad news. 
Here’s a VirtualHost file to start you off; mine came from the default file located at /etc/apache2/mods-enabled/000-default. Inline are comments explaining each part of it.

<VirtualHost *:80>
	# This is some standard config, not a big deal.
	ServerName localhost
	ServerAlias localhost
	ServerAdmin webmaster@localhost

	# Check the end of these files if your server is crashing,
	# they usually have stack dumps of the python error.
	ErrorLog /var/log/apache2/error.log
	CustomLog /var/log/apache2/access.log combined

	# Here is your static directory.  We are saying the files in
	# /var/www/documents/ can be accessed at the root directory,
	# for example http://yoursite/.  This directory is intended for
	# files like HTML and images
	DocumentRoot /var/www/documents

		# Default options (both optional)
		Options FollowSymLinks MultiViews

		# Allow use of .htaccess files (optional)
		AllowOverride None 	

		# Allow viewing of all the subfolders
		Order allow,deny
		allow from all

	# Here we are turning on WSGI.  I'll
	# explain this line in more detail in text below
	WSGIDaemonProcess localhost processes=2 threads=15 display-name=%{GROUP} python-path=/var/www/wsgi-scripts/ python-eggs=/tmp
	WSGIProcessGroup localhost

	# This is saying http://yoursite/myapp should be be processed
	# by the python script at /var/www/wsgi-scripts/myapp.py
	WSGIScriptAlias /myapp /var/www/wsgi-scripts/myapp.py
</VirtualHost>

The line of interest here is the WSGIDaemonProcess directive. This says to start the WSGI module as multiple separate processes.

Not all the options I use all required, here’s why I use each one

  • processes: You must use this if you want script handling to be multithreaded.  The actual number can be whatever you like.
  • threads: Optional. The number of threads for each process, default is 15
  • display-name: Optional. This changes how each spawned process appears when listing processes with the linux command ps
  • python-path: Optional. This adds the provided paths to the PYTHONPATH for spawned processes.  I use the location of our scripts because it is not included by default, so this will allow the handler script we are about to write to import other scripts in the same directory.
  • python-eggs: Optional.  I added this after getting errors about python eggs not being able to be cached.

Testing it out

Now we create our actual handler file that we referenced in the VirtualHost file.  Create the file /var/www/wsgi-scripts/myapp.py, creating the directory if necessary.  In the file, paste this little test snippet and save.

def application(environ, start_response):
    status = '200 OK'
    output = 'Hello there World!'
 
    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
 
    return [output]

Whatever string this function returns will be displayed in your browser. Let’s restart the server and give it a whirl.

sudo /etc/init.d/apache2 restart

Now when you go to http://yourserver/myapp in your web browser, it should display “Hello there world!”.

Notes

  • Whenever you change your script, the server will use the newer one without needing to restart the server.  However if you change any files that your script imports, you will need to have to restart your server in order for it to use the updated version of the script.

Setting Up mod_python on an Ubuntu Rackspace Cloud Server

February 6th, 2010 by derek

I just went in on a Rackspace cloud server to do some very simple web serving through python.  The rackspace cloud wiki doesn’t let users edit it, so I will post my solution here.  The instance I used was Ubuntu Jaunty 9.04, but the installation should work for all versions of Ubuntu, and the configuration for all linux-based servers.

mod_python

This is the bare minimum method way of serving up python files via your web server.  It uses only CGI and mod_python, so each python requests causes a fork of the web server.  Not the most efficient, but it works.  See mod_wsgi for a better solution.

This command will install apache and mod_python.  Not all these packages may be necessary, but it worked for me.

sudo aptitude install apache2 apache2.2-common apache2-mpm-prefork apache2-utils libexpat1 ssl-cert libapache2-mod-python

Next, add a handler to your default configuration which you can edit by running

sudo nano /etc/apache2/sites-enabled/000-default

and add the three lines after the comment below

   Options Indexes FollowSymLinks MultiViews
   AllowOverride None
   Order allow,deny
   allow from all
 
# Add these three lines
   AddHandler mod_python .py
   PythonHandler mod_python.publisher
   PythonDebug On

Restart Apache

/etc/init.d/apache2 restart

Make a test file in your www directory

sudo nano /var/www/test.py

And use the following code

def index(req):
 return "Test successful"

Then test it out at http://youripaddress/test.py.  It should display “Test successful” in your browser.

See Also

  • http://cloudservers.mosso.com/index.php/Ubuntu_-_Apache_and_PHP_install

Mount HFS+ in Ubuntu Live CD with Write Access

November 4th, 2009 by derek

Partitions using Apple’s HFS+ format automatically mounted with read permissions, but not write permissions.  Here’s how I was able to mount my drive with read and write permissions.

Although these steps likely apply to many ubuntu distros, here are the particulars:

  • Western Digital MyBook 1TB formatted HFS+ with Journaling
  • Ubuntu 9.10 Live CD

Up front here are the gotchas

  • Journaling on your HFS+ partition must be turned off, which is easiest done with Disk Utility on OS X
  • You have to manually mount the drive to get write permissions
  • When mounted, sometimes the drive initially is not owned by the current user so in the File Browser it will appear not to be writeable.

Step 1: Disable Journaling

Journaling is a feature of HFS+ that provides protection in case your drive is unsafely removed.  In a nutshell, it keeps a back record of operations that are about to happen on the disk so that if the disk is turned off before the operations actually happen, the drive can quickly recover when it is next plugged in.

To disable it, follow either of these directions sourced from an Apple Support Document.  These require you to have access to OS X.  I am not sure if this is possible through a linux command line.

With Disk Utility

  1. Open Disk Utility (Applications/Utilities)
  2. In the column listing all your drives, select the partition you want to disable journaling for.
  3. Go to File > Disable Journaling.  If it doesn’t pop up, you may have to hold down the option key.

If this succeeds, the Format field at the bottom of the program should say “Mac OS Extended” rather than “Mac OS Extended (Journaled).”  Safely eject your drive in the finder window.

With Command Line

  1. Make sure your drive is plugged in and the partition is mounted (it should show up in finder)
  2. Use the following command, where yourdrivemount is the name of your mounted drive in the Volumes directory:
  3. sudo /usr/sbin/diskutil disableJournal /Volumes/yourdrivemount/

It should print out a message for you saying either journaling was disabled, or it was already disabled.  Safely eject your drive in the finder window!

Step 2: Mount in Ubuntu

This requires some terminal work.  Basically we’re going to plug in the drive, make sure its unmounted, mount it with read/write permissions, and then change the owner to the current user.

  1. Plug in drive, which will likely automatically mount your partition with write access
  2. Find your drive device path by typing in terminal sudo cat /etc/mtab and looking for a line like “/dev/sde3 /media/My\040Book hfsplus …”  In this case, /dev/sde3 is the device path of my partition
  3. Unmount the partition with sudo umount /dev/sde3 where /dev/sde3 is your device path.  The partition should dissapear from your Places column in File Browser
  4. Mount the partition with write access with sudo mount -t hfsplus -o rw /dev/sde3 ~/mybook where /dev/sde3 is your device path and ~/mybook is a directory of your choice (that exists) where you want your partition to be mounted to
  5. If necessary, recursively change the owner of the mount folder to yourself.  On the live cd, my user name is “ubuntu” so I use the command sudo chown -R ubuntu ~/mybook where “ubuntu” is my username and ~/mybook is the folder where you mounted your drive.

The folder should now be read/writeable in the File Browser.  Hope it worked!

Sources

Ubuntu Forums 1
Ubuntu Forms 2
Mac OS X: About File System Journaling
chown
mount
umount

Craigslist Quick Preview Greasemonkey Script

August 30th, 2009 by derek

I recently went through the process of finding a place to live and buying furniture for that place and found clicking through each listing on Craigslist super annoying. So I wrote a Greasemonkey script that makes browsing a ton of listings super easy.  Here it is.

What it does

  • Clicking on a listing link opens stripped-down contents of that listing directly underneath the link – rather than going to another page
  • Pressing Alt-K scrolls through listings downwards, opening one a time.  Alt-J scrolls upwards.

How to get it

  1. Install the Greasemonkey for Firefox if you don’t have it already (and restart browser)
  2. Click this link to install the latest version of the script
  3. Try it out!

Notes

I’ve released the code is released under the MIT license.  It includes code adapted from this script for including jQuery in a Greasemonkey script, also licensed under the MIT license.  If you find a bug or want to contribute you can find the project under Google Code.  Also, feel free to leave any questions in the comments.

Screenshot

Screenshot of the Craigslist Quick Preview Greasemonkey script in action