Deploying a Pyramid App on AppFog
Last July, AppFog revealed it's official plans, which include a free plan that comes with 2GB of RAM. I then decided to give it a try and move a Pyramid app that I had running on a VPS for about a year. The app uses Python 2.7, PostgreSQL, Pyramid 1.3.2 and SQLAlchemy 0.7.8.
On the VPS, the app was running using Waitress behind nginx.
I had to make some minor modifications to the code to make it run on AppFog, which were not really documented anywhere. I decided to post it here, in the hope someone finds it when needed.
Configuration File
First of all, I created a new configuration file. I named it appfog.ini
, but name it whatever you like. I removed the key sqlalchemy.url
, since it is set in environment variables by AppFog. Also, for the app to know that it has to retreive the environment variables instead of using sqlalchemy.url
, I added the key/value appfog = true
.
SQLAlchemy Connection
In main
function of __init__.py
, I replaced the line where the engine is created from the configuration file to take into account that the connection information could come from environment variables. So I replaced:
engine = engine_from_config(settings, 'sqlalchemy.')
with:
if settings.get('appfog') == 'true':
engine = appfog_engine(settings)
else:
from sqlalchemy import engine_from_config
engine = engine_from_config(settings, 'sqlalchemy.')
And I defined appfog_engine
later in the same file:
def appfog_engine(settings):
from sqlalchemy import create_engine
import os, json
all_config = json.loads(os.getenv("VCAP_SERVICES"))
config = all_config['postgresql-9.1'][0]['credentials']
connection_string = ('postgresql+psycopg2://%(username)s:%(password)s'
'@%(host)s:%(port)d/%(name)s')
engine = create_engine(connection_string % config)
return engine
Requirements
Like when you deploy on Heroku, you have to provide a requirements.txt
file, that you generate by running:
$ pip freeze > requirements.txt
WSGI App
You then have to create a wsgi.py
file that you place at the root of your project, beside setup.py
and appfog.ini
. In wsgi.py
, you put:
import os
from paste.deploy import loadapp
os.system("python setup.py develop")
path = os.getcwd()
application = loadapp('config:appfog.ini', relative_to=path)
That's It
Your app is ready to upload using the regular instructions, using the af
commmand line tool provided by AppFog.
Useful Stuff
Since my app was already in production for about a year, I had data in my PostgreSQL database that I had to migrate from my server to AppFog. One nice feature they provide is the ability to make a tunnel to your services. You can find the doc here. With the help of the tunnel, it was easy to use pg_dump
and psql
to migrate the database.