Deploying A WSGI Application On WebFaction

I've been using WebFaction since April 2010 as my webhost. Many of those projects are written in Python and use WSGI. Most often they will be a Flask app of some kind.

Creating The Application

WebFaction has their own custom control panel. We'll use the control panel to provision the application on their servers. This part isn't hard, but it is unique to WebFaction. See their docs for how to create an application, connect it to a domain, and create the website.

The key thing when creating the application is to set the App category to mod_wsgi and then pick the appropriate Python version.

/images/webfaction_wsgi_app.thumbnail.png

Using a VirtualEnv

You can use a virtualenv on WebFaction just like you would in your development environment. The benefits are basically the same: separation of package versions between projects, reproducibility between deployments, a general feeling of smugness.

If you are using virtualenvs you'll want virtualenvwrapper. You'll need to install that yourself. I followed the steps in this excellent post.

Once that is done create a new virtualenv:

mkvirtualenv yourvirtualenv

I prefer to use only packages in my virtualenv. You can use global packages if you like, but you run the risk of upgrading a dependency for one project that breaks another. To use only virtualenv packages you create an empty file called sitecustomize.py in your virtualenv's lib/pythonx.y directory.

Next you want to install the packages required by your project. To get that list pip is your friend. From your development environment:

pip freeze > requirements.txt

Now transfer that server to your host and use it to install the packages:

pip install -r requirements.txt

Updating index.py

When your application was created an index.py file was automatically created within the htdocs directory. This file needs to be edited to activate your virtualenv and to set some paths needed by WSGI.

As an example:

import sys

activate_this='/home/yourAccountName/.virtualenvs/yourVirtualEnvName/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

sys.path.append('/home/yourAccountName/webapps/yourApp/htdocs')

from main import app as application

You will of course replace the paths withe ones to your account's virtualenvs and application directories.

The last line is the statement that starts your application. In my case I have a main.py file that handles starting the app.

Updating httpd.conf

The last file that needs to be edited is the Apache httpd.conf file. It is found in the applications apache2/conf directory. Edit the file to add the following:

WSGIPythonPath /home/yourAccountName/webapps/yourApp/htdocs/
WSGIScriptAlias / /home/yourAccountName/webapps/yourApp/htdocs/index.py

<Directory /home/yourAccountName/webapps/yourApp/htdocs/>
    AddHandler wsgi-script .py
    RewriteEngine on
    RewriteBase /
    WSGIScriptReloading on
</Directory>

This will work if your app is running at the root domain or a subdomain. If you are running in a subdirectory you have some more work to do. But for now, this will remove the .py from the path and give you the kind of URLs you are probably expecting.

Deploy Files and Restart Apache

If you haven't already, now is a good time to move your code to the server. I use mercurial to do this, but you can do it via git, FTP, or whatever method is convenient for you.

Once everything is in place restart Apache so it sees the configuration changes.

apache2/bin/restart

Victory

At this point you should be able to pull up your app in the browser and see it in all its glory.

Comments

Comments powered by Disqus