Multiple Web.py Apps on DreamHost with Passenger

$N*web.py+DreamHost+Passenger = Fun^2$
therefore
$Fun=\sqrt{DreamHost+Passenger+N*web.py}$

A couple weeks ago I had a few hours of fun trying to deploy two web.py applications on DreamHost with Passenger. I got it running and here I’ll tell you how.

This post is complete, but before we proceed, please have a look at the Passenger users guide and keep it handy for reference. Also, it’s a good idea to skim through wiki.dreamhost.com/Passenger, wiki.dreamhost.com/Passenger_WSGI and wiki.dreamhost.com/Web.py to get acquainted to the subject of this post.

This article can also be useful if you need to run a Web.py or any other Python web application — such as Django o Flask — in a sub directory of your domain.

Let’s go by parts.

1) Passenger

If you haven’t yet, enable Passenger for your domain. Log into your DreamHost Control Panel, go to Manage Domains. Whether you are creating a new or changing an existing domain, all you have to do is click a checkbox like the following. Beware that your web directory must end in /public to enable Passenger.

Check everything and hit either “Fully host this domain” or “Change settings”. That was easy.

2) Python 2.7

For this and the next parts we’ll need shell access, so go to your DreamHost Control Panel and enable shell access.

If you check, DreamHost’s Python is a bit old and we want to use a newer one as current libraries need it to be new. So let’s install Python 2.7.3 on our shared DreamHost account under the ~/Python27 directory.

Configure it to install under ~/Python27 — you can change this — build and install it. This will take a few minutes and output lots of lines, of which only errors, if any, will matter:

That’s it! Check your new Python:

Log out and back in and check it’s in the PATH:

Now we’re getting warmed up!

3) Virtualenv

Virtualenv will come handy when installing Python packages, it’s more convenient and IMO easier. We’ll benefit from the newest version of Virtualenv, just grab the single file virtualenv.py and run it:

Let’s use it to create an isolated Python environment:

Activate our virtalenv with:

And install the packages we’ll need, such as:

This makes the virtualenv ready to run some cool web.py apps!

4) Web.py Apps

For this example, we will set up two simple web.py applications and the directory structure will be like the following:

We’ll talk about each of these files.

4.1) passenger_wsgi.py

The files public/app1/passenger_wsgi.py and public/app2/passenger_wsgi.py are the the applications’ bootstraps, and they has to called like that (passenger_wsgi.py) in order to work. Their content is as follows:

4.2) ~/example.com/public/.htaccess

The file ~/example.com/public/.htaccess is where we disable Passenger for the entire domain, among other things. Don’t worry, we’ll enable Passenger where necessary. The content of ~/example.com/public/.htaccess is:

4.3) ~/example.com/public/app*/.htaccess

The files public/app1/.htaccess and public/app2/.htaccess are where we enable Passenger and set the root for each application. Such as in case of app2:

Just a note: the application root does not have to reside in the public tree, it may as well be located at ~/example.com/app3 or anywhere, just don’t forget to set ~example.com/public/app3/.htaccess accordingly:

4.4) ~/example.com/public/app*/tmp/restart.txt

Passenger’s documentation says “By [you] creating or modifying the file tmp/restart.txt in the Rails application’s root folder, Phusion Passenger will automatically restart the application during the next request.” So let us bear in mind we should update this file in case we change our application.

5) Time to see it running!

Go ahead and point your browser to http://example.com/app1 and/or to http://example.com/app2 to see the two applications working independently. Now relax and enjoy!

6) Conclusion

I have had good experiences with Passenger so far. It’s pretty fast and, in my opinion, quite easy to use. Kudos and BIG thanks to the Ruby community!

So, that’s all there is to it! Drop a message in the comment box below, I’d love to read your thoughts.