Enabling Python 2.7 on a PaaS with the OpenShift

Update Since Original Publish Date


Python 2.7 is officially supported
and creating your own cartridge is no longer necessary.

Preface

I have been using OpenShift for a few months now and have to say that I still love it. I’ve sampled most of the other PaaS solutions and feel most comfortable with OpenShift. One of the features I enjoy most in the service is the “do-it-yourself” application. With this, you can run just about anything in a “minimal-hassle”, scalable environment.

I created a quickstart a few weeks ago that had Django running on Python 2.7 in “DIY” mode. This will use some of that, but be a more “step-by-step” approach for newcomers. This example will use the Flask micro-framework as well as the uWSGI application container for a true, production ready environment.

Diving In

The first thing you will need to do is get an OpenShift account (it’s free).

Client Tools

Install the OpenShift client tools:

gem install rhc

** See here if you have trouble getting the tools installed.

Application Setup

Once you have the toolchain setup, we will create the application environment in OpenShift. For this example, we will name our application “py27”.

rhc app create py27 diy-0.1

You will see something similar to:

Creating application: py27 in ehazlett
Now your new domain name is being propagated worldwide (this might take a minute)...
Confirming application 'py27' is available:  Success!

py27 published:  http://py27-ehazlett.rhcloud.com/
git url:  ssh://uuid1234567890@py27-ehazlett.rhcloud.com/~/git/py27.git/
Disclaimer: This is an experimental cartridge that provides a way to try unsupported languages, frameworks, and middleware on Openshift.

You can view the bootstrapped application at http://py27-[namepsace].rhcloud.com

Python 2.7

Now that the application environment is created, we will build and install the latest Python 2.7.x release. To do that, we will first need to get the application SSH credentials.

Run the following to show your application config (enter your account password when prompted):

rhc app show -a py27

You should see something similar to this:

Application Info
================
py27
    Framework: diy-0.1
     Creation: 2012-05-15T22:54:09-04:00
         UUID: 1qaz2wsx3edc4rfv
      Git URL: ssh://1qaz2wsx3edc4rfv@py27-ehazlett.rhcloud.com/~/git/py27.git/
   Public URL: http://py27-ehazlett.rhcloud.com/

 Embedded:
      None

Log into your OpenShift application using the SSH credentials from above (in the Git URL line):

ssh 1qaz2wsx3edc4rfv@py27-[username].rhcloud.com

We will build everything in the OpenShift application tmp directory.

Navigate into the “tmp” directory:

cd $OPENSHIFT_TMP_DIR

Download the latest Python 2.7.x release:

wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2

Extract:

tar jxf Python-2.7.3.tar.bz2

Configure (to put the custom Python into the OpenShift runtime dir):

cd Python-2.7.3

./configure --prefix=$OPENSHIFT_DATA_DIR

Make and install:

make install

You can now check that Python was successfully installed:

$OPENSHIFT_DATA_DIR/bin/python -V

You should get

Python 2.7.3

Supporting Tools

We now have Python installed, but we can’t do much. Part of the common Python toolchain is PIP for Python package management.

Setuptools

Change into the OpenShift “tmp” directory:

cd $OPENSHIFT_TMP_DIR

Download and install setuptools:

wget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz

tar zxf setuptools-0.6c11.tar.gz

cd setuptools-0.6c11

Install:

$OPENSHIFT_DATA_DIR/bin/python setup.py install

PIP

Change into the OpenShift “tmp” directory:

cd $OPENSHIFT_TMP_DIR

Download and install setuptools:

wget http://pypi.python.org/packages/source/p/pip/pip-1.1.tar.gz

tar zxf pip-1.1.tar.gz

cd pip-1.1

Install:

$OPENSHIFT_DATA_DIR/bin/python setup.py install

Application

Okay, so now we have all of the parts needed to run the app. We now need to create the Flask application and configure OpenShift so that it knows how to start and stop it.

First we will create the Flask application. Logout of your OpenShift environment and navigate into the Git repository that was created for your app.

Create a file named application.py in the repo, for example – in the diy folder:

    ??? README
    ??? diy
    ?   ??? index.html
    ?   ??? testrubyserver.rb
    ?   ??? application.py
    ??? misc

BTW, the index.html and testrubyserver.rb are not longer necessary and can be removed anytime.

Edit application.py with the following:

from flask import Flask
import platform
application = Flask(__name__)
 
@application.route("/")
def index():
    return 'Hello from Flask'
 
@application.route("/info")
def info():
    return platform.python_version()

Create a requirements.txt in the root application directory with the following:

uWSGI==1.2.3
Flask==0.8

Directory structure should look like:

??? README
??? diy
?   ??? application.py
?   ??? index.html
?   ??? testrubyserver.rb
??? misc
??? requirements.txt

Hooks

We will now create the hooks that are needed for deployment as well as for starting and stopping the application. In your application Git repository, there is a hidden directory called “.openshift” that contains stubs for the action hooks. We will be editing these.

Edit .openshift/action_hooks/build to have the following:

$OPENSHIFT_DATA_DIR/bin/pip install --use-mirrors -r $OPENSHIFT_REPO_DIR/requirements.txt

Edit .openshift/action_hooks/start to have the following:

$OPENSHIFT_DATA_DIR/bin/uwsgi -s $OPENSHIFT_DIY_IP:$OPENSHIFT_DIY_PORT --socket-protocol http --pp $OPENSHIFT_REPO_DIR/diy --module application -d $OPENSHIFT_DIY_LOG_DIR/app.log --pidfile $OPENSHIFT_TMP_DIR/uwsgi.pid

Edit .openshift/action_hooks/stop to the following:

kill `cat $OPENSHIFT_TMP_DIR/uwsgi.pid`

Deploy

Commit all of the changes to the repository:

git add .

git commit -am "initial commit"

Deploy to OpenShift:

git push

You should now be able to browse and see your application running:

curl http://py27-[namespace].rhcloud.com

Should return:

Hello from Flask

And to verify that your application is using Python 2.7:

curl http://py27-[namespace].rhcloud.com/info

Should return:

2.7.3
Categories
Python
Tags
Comments are closed.