PylonsHQ.

Layout: Fixed-width
  Dashboard > Pylons Cookbook > ... > Deployment > mod_wsgi and workingenv.py
  Pylons Cookbook Log In | Sign Up   View a printable version of the current page.  
  mod_wsgi and workingenv.py
Added by Alberto Valverde, last edited by Mike Orr on Aug 07, 2008  (view change)
Labels: 

Warning

This article is out of date. workingenv has been superceded by virtualenv.

Introduction

mod_wsgi is an Apache module developed by Graham Dumpleton which makes dead easy to run WSGI apps under the Apache web-server.

This recipe explains how to run a Pylons app (although it can be easily adapted to any WSGI app) under mod_wsgi in an isolated workingenv environment in order to host various apps with different library version requirements.

Note: You don't actually need workingenv.py to run Pylons (or any WSGI app for that matter) under mod_wsgi. workingenv.py just provides a convenient way to create controlled and reproducible environments where libraries can be installed. For a simpler setup that doesn't use workingenv check out this document at the official modwsgi site.

Compiling and installing mod_wsgi

You first need to check out mod_wsgi's source from its SVN repository:

1
$ svn co http://modwsgi.googlecode.com/svn/trunk modwsgi

Provided you have Apache's and Python's headers installed, compilation and installation is quite straightforward:

1
2
3
4
$ cd modwsgi
$ ./configure
$ make
$ sudo make install

You then need to edit Apache's httpd.conf so it loads mod_wsgi. In Apache 1.3 you'll need to add:

1
2
LoadModule wsgi_module path_to_modules/mod_wsgi.so
AddModule mod_wsgi.c

If you run into any problems or need compiling it for another version of Apache chechout mod_wsgi's excellent install instructions inside the SVN checkout.

Configuring a VirtualHost

Here is where mod_wsgi shines as it makes it very easy and straightforward. The following lines will suffice, although you will probabbly need to configure other options for a real production site:

1
2
3
4
5
6
7
8
9
<Directory /Users/alberto/wsgi>
    Order allow,deny
    Allow from all
</Directory>

NameVirtualHost *:81
<VirtualHost *:81>
    WSGIScriptAlias / /Users/alberto/wsgi/myapp.wsgi
</VirtualHost>

For the VirtualHost above you should set up apache to listen to port 81 (edit apache's port.conf file). Refer to the Apache documentation for all available options.

Check mod_wsgi is installed correctly

Before even trying to configure your Pylons app and workingenv, first of all check that mod_wsgi runs properly with a "Hello World" app. Write the following app into myapp.wsgi.

1
2
3
4
5
6
7
8
9
def application(environ, start_response):
    status = '200 OK'
    output = 'Hello World!'

    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]

Issue a apachectl restart command and point your web browser to the VirtualHost you just configured. You should see mod_wsgi and your app greeting the world cheerfully. If that's not the case, refer to the Troubleshooting section.

Creating the startup script

As you have probably noticed, the abobe VirtualHost config refers to a file called myapp.wsgi. That file should initialize the python sub-interpreter this script will use (mod_wsgi provides an independent sub-interpreter for each wsgi script by default) and load the WSGI application. Lets see how it looks like

1
2
3
4
5
6
7
8
WORKING_ENV = "/Users/alberto/src/python/environments/N50CPanel"
APP_CONFIG = "/Users/alberto/src/python/checkouts/N50CPanel/development.ini"

import activate_workingenv
activate_workingenv.activate_workingenv(WORKING_ENV)

from paste.deploy import loadapp
application = loadapp("config:" + APP_CONFIG)

That's all it takes to load a Pylons app from its PasteDeploy config file. The above code requires some explanation though:

  • Uses the activate_workingenv script which you'll need to install somewhere in your PYTHONPATH
  • The application is loaded using PasteDeploy's API and bound to the application variable in which mod_wsgi expect to find the WSGI app by default.

Install activate_workingenv.py

Environments created with workinenv.py are usually activated using a shell script. The following script allows activating them from Python (originally found here). Place it in a file called activate_workingenv.py inside the Python site-packages directory where it can be found by the user Apache runs as.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import sys
import os

def activate_workingenv(root):
    """Make modules in a self-contained workingenv available."""

    # Find the workingenv Python package root
    python_version = '.'.join(map(str, sys.version_info[:2]))
    package_root = os.path.join(root, './lib/python' + python_version)

    if package_root not in sys.path:
        # Find and insert setuptools into sys.path, only if it hasn't done
        # before (if the script has been reloaded)
        sys.path.insert(0, package_root)
        real_setuptools = open(os.path.join(package_root,
                                        'setuptools.pth')).read().strip()
        sys.path.insert(0, os.path.join(package_root, real_setuptools))

        # Load all distributions into the working set.
        from pkg_resources import working_set, Environment

        env = Environment(root)
        env.scan()

        distributions, errors = working_set.find_plugins(env)
        for dist in distributions:
            working_set.add(dist)

(Note: This version will not change os.environ['PATH'] nor os.environ['LD_LIBRARY_PATH'] as those are global to the whole Apache process and we don't want or need them changing every time a workingenv is activated)

If you don't have permissions or, for any other reason, you cannot install it at the site-packages directory, alternatively you could modify sys.path inside your .wsgi script like this:

1
2
3
4
import sys
sys.path.append("/directory/where/activate_workingenv.py/lives")
import activate_workingenv
....

Running your app

You should now be able to issue an apachectl restart command and access your Pylons app at the VirtualHost you just configured. Keep in mind though:

  • Your data dir should be writable by the user Apache runs as.
  • EvalException should be disabled if running in a multi-process Apache MPM

Troubleshooting

If anything goes wrong, first check your apache error.log, double-check the files you created and refer to mod_wsgi's documentation.

Conclusion

mod_wsgi and workingenv are a great combination when used together to host multiple apps in an Apache process:

  • mod_wsgi is dead easy to configure, lightweight and the fastest apache-wsgi gateway yet. It's still in dev though.
  • workingenv creates nicely isolated environments where you can install different versions of the same eggs side by side in the same machine.

Together they allow to host several independent WSGI apps, along their different requirements in the same Apache process.

Hmmm, I'm beginning to smell Python commodity hosting... :)

EvalException could be disabled (safely?) by appending the line

1
full_stack = False

to your development.ini configuration file. Almost no documentation around.

Posted by Daniele Paolella at Jul 23, 2007 16:13 | Permalink
Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators

Powered by Pylons - Contact Administrators