Shared Server CherryPy Installation
Sept. 18, 2014

Caution: This post is several years old. It was transferred from my old website. The advise below may or may not still be relevant. Proceed with caution.

Introduction

The CherryPy Python web framework is an incredibly cool way to develop web applications. However, since it is a server in itself, you must have your own server machine, or have a dedicated server. But most simple web developers might not own their own server; they might be using a shared server.

So can you install and use CherryPy on a shared server? The answer is yes, but not without a lot of pain and frustration. After several months of trying to get it to work properly, without the help of any good tutorial, I have decided to create this tutorial to help out anyone who just wants to be able to use CherryPy. This tutorial will guide you through the steps of successfully installing, configuring, and using CherryPy.

Contents

  • About this tutorial
  • Terms to know
  • Getting started
    • How to get SSH access
  • Installation
    • Installing Python
    • Installing Flup
    • Installing CherryPy
  • Setting up a sample application
    • Testing
  • Configuration
  • Conclusion

About this tutorial

This tutorial can be adapted to any shared server, but I will be mainly using Bluehost.com as examples.

Terms to know

FCGI:Fast CGI is a variation of CGI (common gateway interface). It is a protocol for interfacing interactive programs with a web server. It is the method we will use to run CherryPy on Bluehost.

Flup:Flup offers three sets of WSGI servers/gateways, which speak AJP 1.3, FastCGI, and SCGI. We will use flup for FastCGI. You will need flup installed for CherryPy to work.

Getting started

What you will need:

  • SSH access to your Bluehost account
  • Some familiarity with shell scripting
  • Some knowledge of linux operating system

How to get SSH access

  1. Log into the Bluehost.com control panel.
  2. Scroll down to the "Security" section, and click "SSH/Shell Access."
  3. You will then need to upload a photo ID of some kind.
  4. Bluehost will contact you when your SSH access is enabled. (It usually takes about a day or 2.)
  5. Once your SSH access is enabled, you will be able to connect using a linux or mac terminal, or PuTTY on Windows. A command like this will make the connection:
ssh username@domain.com

Installation

Some services must be installed prior to installing CherryPy. You may need to install them depending if whether they are not already installed.

  • Python
  • Flup
  • CherryPy

Installing Python

Execute the following commands on your Bluehost server, through SSH:

cd ~
mkdir src
cd src
pyv=2.6
wget http://python.org/ftp/python/$pyv/Python-$pyv.tgz
tar xzf Python-$pyv.tgz
cd Python-$pyv
./configure --prefix="$HOME"
make
make install

You will need to add your home directory to the $PATH to make the shell run the new python. Use VI or another text editor to edit your .bash_profile:

sudo vi ~/.bash_profile

Navigate with the arrow keys, and press 'a' to start typing. If you mess up, press escape, then type ':q' to quit without saving. To save, press escape, then 'ZZ' (hold shift key).
Ensure the export statement looks like the following:

export PATH=$HOME/bin:${PATH}

Reload the shell, and continue.

Installing Flup

Execute the following commands:

flupv=1.0.2
cd ~
mkdir src
cd ~/src
wget http://www.saddi.com/software/flup/dist/flup-$flupv.tar.gz
tar -xzf flup-$flupv.tar.gz
cd flup-$flupv
sudo python setup.py install

Installing CherryPy

Execute the following commands:

chv=3.1.2
cd ~
mkdir src
cd ~/src
wget http://download.cherrypy.org/cherrypy/$chv/CherryPy-$chv.tar.gz
tar -xzf CherryPy-$chv.tar.gz
cd CherryPy-$chv
sudo python setup.py install

Setting up a sample application

Inside the cgi-bin in your public_html directory, or whatever directory is your website's root, create the following 2 files:

  • cherryd.fcgi: the file that will be executed.
  • run.py: your application's main launcher.

cherryd.fcgi:

#!/~/bin/python
"""The CherryPy daemon."""

import sys

import cherrypy
from cherrypy.process import plugins, servers


def start(configfiles=None, daemonize=False, environment=None,
          fastcgi=False, scgi=False, pidfile=None, imports=None, cgi=False):
    """Subscribe all engine plugins and start the engine."""
    sys.path = [''] + sys.path
    for i in imports or []:
        exec("import %s" % i)
    
    for c in configfiles or []:
        cherrypy.config.update(c)
        # If there's only one app mounted, merge config into it.
        if len(cherrypy.tree.apps) == 1:
            for app in cherrypy.tree.apps.values():
                app.merge(c)
    
    engine = cherrypy.engine
    
    if environment is not None:
        cherrypy.config.update({'environment': environment})
    
    # Only daemonize if asked to.
    if daemonize:
        # Don't print anything to stdout/sterr.
        cherrypy.config.update({'log.screen': False})
        plugins.Daemonizer(engine).subscribe()
    
    if pidfile:
        plugins.PIDFile(engine, pidfile).subscribe()
    
    if hasattr(engine, "signal_handler"):
        engine.signal_handler.subscribe()
    if hasattr(engine, "console_control_handler"):
        engine.console_control_handler.subscribe()
    
    if fastcgi + scgi + cgi > 1:
        # Only one *cgi mode permitted
        cherrypy.log.error("Only one of scgi, fastcgi, and cgi are allowed.",
                           'ENGINE')
        sys.exit(1)
    elif fastcgi + scgi + cgi == 1:
        # Turn off autoreload when using *cgi.
        cherrypy.config.update({'engine.autoreload_on': False})
        # Turn off the default HTTP server (which is subscribed by default).
        cherrypy.server.unsubscribe()
        
        addr = cherrypy.server.bind_addr
        #import glu
        #glu.log( str( addr ), "cherryd.fcgi bind_addr")
        if fastcgi:
            f = servers.FlupFCGIServer(application=cherrypy.tree,
                                       bindAddress=addr)
        elif scgi:
            f = servers.FlupSCGIServer(application=cherrypy.tree,
                                       bindAddress=addr)
        else:
            f = servers.FlupCGIServer(application=cherrypy.tree,
                                      bindAddress=addr)
        s = servers.ServerAdapter(engine, httpserver=f, bind_addr=addr)
        s.subscribe()
    
    # Always start the engine; this will start all other services
    try:
        engine.start()
    except:
        # Assume the error has been logged already via bus.log.
        sys.exit(1)
    else:
        engine.block()


if __name__ == '__main__':
   cherrypy.config.update({
        'server.socket_port': None,
        'server.socket_host': '0.0.0.0',
        'server.socket_file': None,
        'server.script_name': 'cgi-bin/cherryd.fcgi'
   })
   start( daemonize=False, fastcgi=True, imports=["run"])

The cherryd.fcgi file must have the correct permissions. Run the following to set the permissions:

chmod 755 cherryd.fcgi

run.py:

import cherrypy

class HelloWorld:
	@cherrypy.expose
  	def index(self):
    	return 'Hello World!!!!'

cherrypy.tree.mount(HelloWorld(), '/cgi-bin/cherryd.fcgi/')

# CherryPy autoreload must be disabled for the flup server to work
cherrypy.config.update({'engine.autoreload_on':False})

Testing

Now that you have the 2 files, test that the application works, by navigating to it in your browser, like this: http://www.your-domain.com/cgi-bin/cherryd.fcgi/ (note the trailing slash!)
If all is correct, you will see "Hello World!!!" displayed in your browser.

Configuration

Now that you have your application running, you need to cause your server to redirect to the cherryd.fcgi file, so that you won't have directly call it. You also need to tell the server how to handle .fcgi files. In your .htaccess file, add the following lines:

AddHandler fcgid-script .fcgi
RewriteEngine on
RewriteRule ^(cgi-bin/cherryd.fcgi/.*)$ - [last]
RewriteRule ^(.*)$ /cgi-bin/cherryd.fcgi/$1 [last]

The first line lets the server know that files ending in .fcgi should be treated as fcgi-scripts. The second line makes sure the abiltiy to re-write rules is enabled. The second line is very important. The third line ensures that whenever the application is accessed directly, the rest of the .htaccess rules will be ignored. The fourth line redirects all URLs to the cherryd.fcgi file.

You will naw be able to navigate to http://www.your-domain.com/ to access your application.

Conclusion

Hopefully now you have a working CherryPy server. To deploy your real application, simply change the run.py to import and run the application.

Happy CherryPy development!

comments powered by Disqus