Deploying on Heroku

[heroku]

Heroku is a modern and agile multiplatform hosting solution. It allows you to push your applications to a cloud server using Git. In order to use Heroku you must have Git and the Heroku SDK installed. You interact with Heroku using the SDK locally and your commands will be pushed and executed on the server.

Applications running on Heroku cannot rely on a persistent filesystem since it is refreshed periodically, for this reason only the application code can be stored on the file system. All data must be stored in the database. Heroku relies on PostgreSQL. Yet the PostgreSQL is also configured using the Heroku SDK and the URI for the database is assigned dynamically at run-time and stored in an environment variable.

This means that web2py applications must be modified to work on Heroku in order to use the database.

Web2py provides a “heroku.sh” script to help you. All you need to do is replace:

  1. db = DAL(...)

in your code with:

  1. from gluon.contrib.heroku import get_db
  2. db = get_db(name=None, pool_size=10)

Here name is the environment variable containing the Heroku PostgreSQL URI (something like HEROKU_POSTGRESQL_RED_URL). It defaults to None and if there is only one HEROKU_POSTGRESQL_*_URL environment variable it will use that. pool_size is the usual DAL pool size.

When non-running on the Heroku platform get_db will use a development database “sqlite://heroku.test.sqlite”.

In both cases sessions will be stored in database.

Web2py provides a script “scripts/setup-web2py-heroku.sh” to deploy your web2py installation on heroku. It performs the following steps:

It installs virtualenv and the psycopg2 driver:

  1. sudo pip install virtualenv
  2. sudo pip install psycopg2

It creates and activates a virtualenv

  1. virtualenv venv --distribute
  2. source venv/bin/activate

Then creates a requirement file:

  1. pip freeze > requirements.txt

And creates a “Procfile” which tells Heroku how to start web2py:

  1. echo "web: python web2py.py -a 'yourpassword' -i 0.0.0.0 -p $PORT" > Procfile

You can change this line to use a different server. You must edit it to select your own admin password. $PORT is a variable which is correctly escaped since its value is set at runtime. You should also consider starting web2py with gunicorn using anyserver.py since this is one of the recommended web servers for Python.

Finally the script creates a Git repository:

  1. git init
  2. git add .
  3. git add Procfile
  4. git commit -a -m "first commit"

pushes everything to Heroku, and starts it:

  1. heroku create
  2. git push heroku master
  3. heroku addons:add heroku-postgresql:dev
  4. heroku scale web=1
  5. heroku open

heroku here is a shell command part of the Heroku SDK.

We thank Craig Krestiens from Heroku for his help with this recipe.