Quick and Dirty Python
Deployments with HerokuDeployments with Heroku
Guest starring Flask, CoffeeScript, Fabric, and SeatGeek
Daniel Pritchett for MEMpy,
March 19, 2012
Painless Heroku Startup
Requirements
• Python 2.7
• virtualenv
• pip
• Rubygems• Rubygems
• Procfile / foreman
Get started
• Install git, foreman, pip, virtualenv
• Clone/create a repo with a Procfile that
starts a HTTP service
• foreman start to test it locally• foreman start to test it locally
• heroku create app_name –
stack=cedar && git push heroku
master
Setup log
$ virtualenv --no-site-packages heroku_demo
New python executable in heroku_demo/bin/python
Installing pip...............cdone.
$ cd heroku_demo/
$ . bin/activate
$ git clone git://github.com/dpritchett/wwebsite-python.git app
$ cd app
$ pip install -r ./requirements.txt
Successfully installed Flask Jinja2 Pygments Werkzeug chardet gunicorn
$ foreman start
13:20:18 web.1 | started with pid 17810
13:20:18 web.1 | 2012-03-19 13:20:18 [17810] [INFO] Starting gunicorn 0.14.1
13:20:18 web.1 | 2012-03-19 13:20:18 [17810] [INFO] Listening at: http://0.0.0.0:5000
$ heroku create mempy-demo --stack=cedar
Creating mempy-demo... done, stack is cedar
http://mempy-demo.herokuapp.com/ | [email protected]:mempy-demo.git
Git remote heroku added
$ git push heroku master
Procfile declares types -> web
http://mempy-demo.herokuapp.com deployed to Heroku
$ curl mempy-demo.herokuapp.com
Hello World!
Foreman’s Procfile defines the service
web: gunicorn app:APP -b 0.0.0.0:$PORT -w 3
You can run the same thing at the console to test:You can run the same thing at the console to test:
$ gunicorn app:APP -b 0.0.0.0:$PORT -w 3
Heroku logging• Captures stdout, stderr
• You’ll need it since you have no persistent disk
• Simplest case you can just use a print statement
• Free plan has limitations
• Consider an offsite log manager
Remote console
$ heroku run bash
Running bash attached to terminal... up, run.2
~ $ find templates
templates
templates/index.html
~ $ find static
static
static/jsstatic/js
static/js/memphis_tickets.js
static/coffee
static/coffee/memphis_tickets.coffee
static/bootstrap
static/bootstrap/js
static/bootstrap/js/bootstrap.js
...
static/bootstrap/css/bootstrap.css
static/css
static/css/tickets.css
~ $
Sample Flask application:
TicketsOfMemphis.com
The entire backend
HTML templating (Jinja2)
CoffeeScript excerpts
Data provided by SeatGeek API
Honorable mention: Fabric$ fab s
[localhost] local: coffee -o ../js/ --compile
./*coffee
[localhost] local: foreman start
14:11:29 web.1 | started with pid 24218
14:11:29 web.1 | 2012-03-19 14:11:29
[24218] [INFO] Starting gunicorn 0.14.1
14:11:29 web.1 | 2012-03-19 14:11:29
[24218] [INFO] Listening at: http://0.0.0.0:5000
(24218)
14:11:29 web.1 | 2012-03-19 14:11:29
[24218] [INFO] Using worker: sync[24218] [INFO] Using worker: sync
14:11:29 web.1 | 2012-03-19
14:11:29 [24225] [INFO] Booting worker with pid:
24225
14:11:29 web.1 | 2012-03-19 14:11:29
[24226] [INFO] Booting worker with pid: 24226
14:11:29 web.1 | 2012-03-19 14:11:29
[24227] [INFO] Booting worker with pid: 24227
Heroku Ecosystem
Pain points and add-ons
addons.heroku.com
• Databases
• Worker hours
• Email services
• DNS• DNS
• HTTPS and certificates
• Billing
• Message/Task Queues
LogEntries
LogEntries Alerts
Zerigo DNS
MongoHQ
Thank you!
Try a copy of the code at
github.com/dpritchett/wwebsite-python
Heroku and Flask have great docs.Heroku and Flask have great docs.
Find me @dpritchett
Recommended