Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
lanyrd.com/sdmbmk
Heroku 101
!
dgouldin@heroku.com
@dgouldin
lanyrd.com/sdmbmk
What is Heroku?
The application platform
lanyrd.com/sdmbmk
You write your app.
We do the rest.
lanyrd.com/sdmbmk
LOW HIGH
SCALE
drag to scale
lanyrd.com/sdmbmk
5 Billion
requests per day
3+ Million
Apps Created
125+
Add-on services
lanyrd.com/sdmbmk
What’s a Heroku app?
lanyrd.com/sdmbmk
The Twelve-Factor app
12factor.net
lanyrd.com/sdmbmk
Let’s dive in!
lanyrd.com/sdmbmk
Assumptions
You want to learn about Heroku.
You know (a bit) of Python.
You have Python, pip, and virtua...
lanyrd.com/sdmbmk
*install.python-guide.org
lanyrd.com/sdmbmk
Install the Toolbelt
toolbelt.heroku.com
lanyrd.com/sdmbmk
$ heroku login
Log in
lanyrd.com/sdmbmk
X. Dev/prod parity
12factor.net/dev-prod-parity
lanyrd.com/sdmbmk
Create a Flask app
devcenter.heroku.com/articles/getting-started-with-python
lanyrd.com/sdmbmk
$ mkdir hello-heroku
$ cd hello-heroku
$ virtualenv venv
$ source venv/bin/activate
$ pip install Flask ...
lanyrd.com/sdmbmk
import os
from flask import Flask
!
app = Flask(__name__)
!
@app.route('/')
def hello():
return 'Hello W...
lanyrd.com/sdmbmk
web: gunicorn hello:app
Procfile
lanyrd.com/sdmbmk
VI. Processes
12factor.net/
lanyrd.com/sdmbmk
$ foreman start
Start the app
lanyrd.com/sdmbmk
X. Dev/prod parity
12factor.net/dev-prod-parity
lanyrd.com/sdmbmk
$ pip freeze > requirements.txt
Freeze dependencies
lanyrd.com/sdmbmk
II. Dependencies
12factor.net/
lanyrd.com/sdmbmk
Store the app in git
devcenter.heroku.com/articles/git
lanyrd.com/sdmbmk
venv
*.pyc
.gitignore
lanyrd.com/sdmbmk
$ git init
$ git add .
$ git commit -m "initial commit"
Store the app in git
lanyrd.com/sdmbmk
I. Single codebase
12factor.net/
lanyrd.com/sdmbmk
Create and deploy 

the application
lanyrd.com/sdmbmk
$ heroku create
$ git push heroku master
...
-----> Launching... done, v2
http://happy-pycon-2015.heroku...
lanyrd.com/sdmbmk
V. Build, release, run
12factor.net/build-release-run
lanyrd.com/sdmbmk
Logging
lanyrd.com/sdmbmk
$ heroku logs --tail
Viewing logs
lanyrd.com/sdmbmk
import os
from flask import Flask
!
app = Flask(__name__)
!
import logging
logging.basicConfig(level=log...
lanyrd.com/sdmbmk
$ git add .
$ git commit -m "add logging"
$ git push heroku master
Commit and deploy again
lanyrd.com/sdmbmk
$ heroku logs --tail
Viewing logs
lanyrd.com/sdmbmk
XI. Logs as event streams
12factor.net/
lanyrd.com/sdmbmk
Configuration variables
devcenter.heroku.com/articles/config-vars
lanyrd.com/sdmbmk
import os
import logging
from flask import Flask
!
app = Flask(__name__)
logging.basicConfig(level=loggi...
lanyrd.com/sdmbmk
$ NAME=David foreman start
Try it out locally
lanyrd.com/sdmbmk
$ echo "NAME=David" > .env
Store local env vars in .env
(don’t forget to add it to .gitignore)
lanyrd.com/sdmbmk
$ foreman start
Try it out locally
lanyrd.com/sdmbmk
$ git add .
$ git commit -m "add name"
$ git push heroku master
Commit and deploy
lanyrd.com/sdmbmk
$ heroku config:set NAME=David
Setting config vars and restarting happy-pycon-2015... done, v6
!
$ herok...
lanyrd.com/sdmbmk
III. Store config in the environment
12factor.net/
lanyrd.com/sdmbmk
Releases
devcenter.heroku.com/articles/releases
lanyrd.com/sdmbmk
$ heroku releases
=== happy-pycon-2015 Releases
v7 Remove NAME config vars dgouldin@heroku.com 2015/04/0...
lanyrd.com/sdmbmk
I. One codebase, many deploys
12factor.net/
lanyrd.com/sdmbmk
Addons
addons.heroku.com
lanyrd.com/sdmbmk
$ heroku addons:create rediscloud
Adding rediscloud on happy-pycon-2015... done, v8 (free)
Use `heroku a...
lanyrd.com/sdmbmk
import os
import redis
from flask import Flask
!
app = Flask(__name__)
db = redis.from_url(os.environ['R...
lanyrd.com/sdmbmk
IV. Treat backing services as attached resources
12factor.net/
lanyrd.com/sdmbmk
$ pip install redis
$ pip freeze > requirements.txt
Dependencies
lanyrd.com/sdmbmk
$ git add .
$ git commit -m "use redis for name"
$ git push heroku master
Commit and deploy
lanyrd.com/sdmbmk
X. Dev/prod parity?
Uh oh…
lanyrd.com/sdmbmk
$ foreman start
13:03:34 web.1 | started with pid 24492
...
13:03:34 web.1 | 2015-04-07 13:03:34 [24495]...
lanyrd.com/sdmbmk
Some solutions:
Only run remotely
Homebrew - brew.sh
Vagrant - vagrantup.com
Docker - docker.io
lanyrd.com/sdmbmk
Scaling and performance
devcenter.heroku.com/articles/scaling
lanyrd.com/sdmbmk
$ heroku ps:scale web=2
Scaling dynos... done, now running web at 2:1X.
!
$ heroku ps:scale web=10
Scali...
lanyrd.com/sdmbmk
Understanding performance
devcenter.heroku.com/articles/optimizing-dyno-usage
lanyrd.com/sdmbmk
VIII. Concurrency via processes
12factor.net/
lanyrd.com/sdmbmk
$ heroku labs:enable log-runtime-metrics
$ heroku restart
!
$ heroku logs --tail
2015-04-07T17:19:30.746...
lanyrd.com/sdmbmk
Dashboard
metrics
organization
add-ons marketplace
lanyrd.com/sdmbmk
Metrics
devcenter.heroku.com/articles/metrics
lanyrd.com/sdmbmk
Organizations
devcenter.heroku.com/categories/organization-accounts
lanyrd.com/sdmbmk
Add-ons Marketplace
lanyrd.com/sdmbmk
Papertrail
lanyrd.com/sdmbmk
Rollbar
lanyrd.com/sdmbmk
New Relic
lanyrd.com/sdmbmk
And many more …
addons.heroku.com
lanyrd.com/sdmbmk
Github Integration
devcenter.heroku.com/articles/github-integration
lanyrd.com/sdmbmk
Automatic Deploys
lanyrd.com/sdmbmk
Release Diffs
lanyrd.com/sdmbmk
Heroku Button
1 click to a deployed Heroku app
lanyrd.com/sdmbmk
app.json
lanyrd.com/sdmbmk
README.md
[![Deploy](https://www.herokucdn.com/deploy/button.png)]
(https://heroku.com/deploy?template=h...
lanyrd.com/sdmbmk
Try it yourself!
github.com/dgouldin/django-playground
lanyrd.com/sdmbmk
Bonus: Platform API
devcenter.heroku.com/categories/platform-api
lanyrd.com/sdmbmk
>>> import json
>>> import requests # python-requests.org
!
>>> heroku = requests.session()
>>> heroku.a...
lanyrd.com/sdmbmk
>>> heroku.get('https://api.heroku.com/apps/happy-pycon-2015').json()
{u'archived_at': None,
...
u'web_u...
lanyrd.com/sdmbmk
>>> heroku.get('https://api.heroku.com/apps/happy-pycon-2015/formation').json()
[{u'command': u'gunicorn...
lanyrd.com/sdmbmk
Questions and Free Play
dgouldin@heroku.com
@dgouldin
Upcoming SlideShare
Loading in …5
×

Heroku 101 py con 2015 - David Gouldin

5,993 views

Published on

David Gouldin @Heroku gave a talk at Py Con 2015 - check it out.

Published in: Technology
  • I like this service ⇒ www.HelpWriting.net ⇐ from Academic Writers. I don't have enough time write it by myself.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Dating direct: ❤❤❤ http://bit.ly/2ZDZFYj ❤❤❤
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Sex in your area is here: ❤❤❤ http://bit.ly/2ZDZFYj ❤❤❤
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Heroku 101 py con 2015 - David Gouldin

  1. 1. lanyrd.com/sdmbmk Heroku 101 ! dgouldin@heroku.com @dgouldin
  2. 2. lanyrd.com/sdmbmk What is Heroku? The application platform
  3. 3. lanyrd.com/sdmbmk You write your app. We do the rest.
  4. 4. lanyrd.com/sdmbmk LOW HIGH SCALE drag to scale
  5. 5. lanyrd.com/sdmbmk 5 Billion requests per day 3+ Million Apps Created 125+ Add-on services
  6. 6. lanyrd.com/sdmbmk What’s a Heroku app?
  7. 7. lanyrd.com/sdmbmk The Twelve-Factor app 12factor.net
  8. 8. lanyrd.com/sdmbmk Let’s dive in!
  9. 9. lanyrd.com/sdmbmk Assumptions You want to learn about Heroku. You know (a bit) of Python. You have Python, pip, and virtualenv*.
  10. 10. lanyrd.com/sdmbmk *install.python-guide.org
  11. 11. lanyrd.com/sdmbmk Install the Toolbelt toolbelt.heroku.com
  12. 12. lanyrd.com/sdmbmk $ heroku login Log in
  13. 13. lanyrd.com/sdmbmk X. Dev/prod parity 12factor.net/dev-prod-parity
  14. 14. lanyrd.com/sdmbmk Create a Flask app devcenter.heroku.com/articles/getting-started-with-python
  15. 15. lanyrd.com/sdmbmk $ mkdir hello-heroku $ cd hello-heroku $ virtualenv venv $ source venv/bin/activate $ pip install Flask gunicorn Create a vitualenv and install requirements
  16. 16. lanyrd.com/sdmbmk import os from flask import Flask ! app = Flask(__name__) ! @app.route('/') def hello(): return 'Hello World!' hello.py
  17. 17. lanyrd.com/sdmbmk web: gunicorn hello:app Procfile
  18. 18. lanyrd.com/sdmbmk VI. Processes 12factor.net/
  19. 19. lanyrd.com/sdmbmk $ foreman start Start the app
  20. 20. lanyrd.com/sdmbmk X. Dev/prod parity 12factor.net/dev-prod-parity
  21. 21. lanyrd.com/sdmbmk $ pip freeze > requirements.txt Freeze dependencies
  22. 22. lanyrd.com/sdmbmk II. Dependencies 12factor.net/
  23. 23. lanyrd.com/sdmbmk Store the app in git devcenter.heroku.com/articles/git
  24. 24. lanyrd.com/sdmbmk venv *.pyc .gitignore
  25. 25. lanyrd.com/sdmbmk $ git init $ git add . $ git commit -m "initial commit" Store the app in git
  26. 26. lanyrd.com/sdmbmk I. Single codebase 12factor.net/
  27. 27. lanyrd.com/sdmbmk Create and deploy 
 the application
  28. 28. lanyrd.com/sdmbmk $ heroku create $ git push heroku master ... -----> Launching... done, v2 http://happy-pycon-2015.herokuapp.com deployed to Heroku $ heroku open Create and deploy the app
  29. 29. lanyrd.com/sdmbmk V. Build, release, run 12factor.net/build-release-run
  30. 30. lanyrd.com/sdmbmk Logging
  31. 31. lanyrd.com/sdmbmk $ heroku logs --tail Viewing logs
  32. 32. lanyrd.com/sdmbmk import os from flask import Flask ! app = Flask(__name__) ! import logging logging.basicConfig(level=logging.DEBUG) ! @app.route('/') def hello(): logging.info("saying hello") return 'Hello World!' hello.py
  33. 33. lanyrd.com/sdmbmk $ git add . $ git commit -m "add logging" $ git push heroku master Commit and deploy again
  34. 34. lanyrd.com/sdmbmk $ heroku logs --tail Viewing logs
  35. 35. lanyrd.com/sdmbmk XI. Logs as event streams 12factor.net/
  36. 36. lanyrd.com/sdmbmk Configuration variables devcenter.heroku.com/articles/config-vars
  37. 37. lanyrd.com/sdmbmk import os import logging from flask import Flask ! app = Flask(__name__) logging.basicConfig(level=logging.DEBUG) ! @app.route('/') def hello(): logging.info("saying hello") name = os.environ.get('NAME', 'World') return 'Hello {}!'.format(name) hello.py
  38. 38. lanyrd.com/sdmbmk $ NAME=David foreman start Try it out locally
  39. 39. lanyrd.com/sdmbmk $ echo "NAME=David" > .env Store local env vars in .env (don’t forget to add it to .gitignore)
  40. 40. lanyrd.com/sdmbmk $ foreman start Try it out locally
  41. 41. lanyrd.com/sdmbmk $ git add . $ git commit -m "add name" $ git push heroku master Commit and deploy
  42. 42. lanyrd.com/sdmbmk $ heroku config:set NAME=David Setting config vars and restarting happy-pycon-2015... done, v6 ! $ heroku config:get NAME David ! $ heroku config === happy-pycon-2015 Config Vars NAME: David ! $ heroku config:unset NAME Unsetting NAME and restarting happy-pycon-2015... done, v7 Managing config vars
  43. 43. lanyrd.com/sdmbmk III. Store config in the environment 12factor.net/
  44. 44. lanyrd.com/sdmbmk Releases devcenter.heroku.com/articles/releases
  45. 45. lanyrd.com/sdmbmk $ heroku releases === happy-pycon-2015 Releases v7 Remove NAME config vars dgouldin@heroku.com 2015/04/07 12:41:49 v6 Deploy df3cf06 dgouldin@heroku.com 2015/04/07 12:40:32 v5 Set NAME config vars dgouldin@heroku.com 2015/04/07 12:35:30 v4 Deploy 5bebf9b dgouldin@heroku.com 2015/04/07 12:34:27 v3 Deploy 69398b3 dgouldin@heroku.com 2015/04/07 12:18:08 v2 Enable Logplex dgouldin@heroku.com 2015/04/07 12:16:20 v1 Initial release dgouldin@heroku.com 2015/04/07 12:16:17 Release history
  46. 46. lanyrd.com/sdmbmk I. One codebase, many deploys 12factor.net/
  47. 47. lanyrd.com/sdmbmk Addons addons.heroku.com
  48. 48. lanyrd.com/sdmbmk $ heroku addons:create rediscloud Adding rediscloud on happy-pycon-2015... done, v8 (free) Use `heroku addons:docs rediscloud` to view documentation. Adding an addon
  49. 49. lanyrd.com/sdmbmk import os import redis from flask import Flask ! app = Flask(__name__) db = redis.from_url(os.environ['REDISCLOUD_URL']) ! @app.route('/') def hello(): name = db.get(‘name') or 'World' return 'Hello %s!' % name ! @app.route('/setname/<name>') def setname(name): db.set('name', name) return 'Name updated.' hello.py
  50. 50. lanyrd.com/sdmbmk IV. Treat backing services as attached resources 12factor.net/
  51. 51. lanyrd.com/sdmbmk $ pip install redis $ pip freeze > requirements.txt Dependencies
  52. 52. lanyrd.com/sdmbmk $ git add . $ git commit -m "use redis for name" $ git push heroku master Commit and deploy
  53. 53. lanyrd.com/sdmbmk X. Dev/prod parity? Uh oh…
  54. 54. lanyrd.com/sdmbmk $ foreman start 13:03:34 web.1 | started with pid 24492 ... 13:03:34 web.1 | 2015-04-07 13:03:34 [24495] [ERROR] Exception in worker process: 13:03:34 web.1 | Traceback (most recent call last): ... 13:03:34 web.1 | KeyError: 'REDISCLOUD_URL' ... 13:03:34 web.1 | 2015-04-07 13:03:34 [24495] [INFO] Worker exiting (pid: 24495) 13:03:34 web.1 | 2015-04-07 13:03:34 [24492] [INFO] Shutting down: Master 13:03:34 web.1 | 2015-04-07 13:03:34 [24492] [INFO] Reason: Worker failed to boot. 13:03:34 web.1 | exited with code 3 13:03:34 system | sending SIGTERM to all processes SIGTERM received Uh oh…
  55. 55. lanyrd.com/sdmbmk Some solutions: Only run remotely Homebrew - brew.sh Vagrant - vagrantup.com Docker - docker.io
  56. 56. lanyrd.com/sdmbmk Scaling and performance devcenter.heroku.com/articles/scaling
  57. 57. lanyrd.com/sdmbmk $ heroku ps:scale web=2 Scaling dynos... done, now running web at 2:1X. ! $ heroku ps:scale web=10 Scaling dynos... done, now running web at 10:1X. ! $ heroku ps:scale web=5:2X Scaling dynos... done, now running web at 5:2X. ! $ heroku ps:scale web=1:PX Scaling dynos... done, now running web at 1:PX. ! $ heroku ps:scale web=1:1X Scaling dynos... done, now running web at 1:1X. Scaling
  58. 58. lanyrd.com/sdmbmk Understanding performance devcenter.heroku.com/articles/optimizing-dyno-usage
  59. 59. lanyrd.com/sdmbmk VIII. Concurrency via processes 12factor.net/
  60. 60. lanyrd.com/sdmbmk $ heroku labs:enable log-runtime-metrics $ heroku restart ! $ heroku logs --tail 2015-04-07T17:19:30.746857+00:00 heroku[web.1]: source=web.1 dyno=heroku. 23939571.b4d17f84-50f5-4e2f-9fb1-b2124db4addb sample#memory_total=17.86MB sample#memory_rss=17.85MB sample#memory_cache=0.00MB sample#memory_swap=0.00MB sample#memory_pgpgin=5311pages sample#memory_pgpgout=740pages ! 2015-04-07T17:19:50.787234+00:00 heroku[web.1]: source=web.1 dyno=heroku. 23939571.b4d17f84-50f5-4e2f-9fb1-b2124db4addb sample#memory_total=17.86MB sample#memory_rss=17.85MB sample#memory_cache=0.00MB sample#memory_swap=0.00MB sample#memory_pgpgin=5311pages sample#memory_pgpgout=740pages log-runtime-metrics
  61. 61. lanyrd.com/sdmbmk Dashboard metrics organization add-ons marketplace
  62. 62. lanyrd.com/sdmbmk Metrics devcenter.heroku.com/articles/metrics
  63. 63. lanyrd.com/sdmbmk Organizations devcenter.heroku.com/categories/organization-accounts
  64. 64. lanyrd.com/sdmbmk Add-ons Marketplace
  65. 65. lanyrd.com/sdmbmk Papertrail
  66. 66. lanyrd.com/sdmbmk Rollbar
  67. 67. lanyrd.com/sdmbmk New Relic
  68. 68. lanyrd.com/sdmbmk And many more … addons.heroku.com
  69. 69. lanyrd.com/sdmbmk Github Integration devcenter.heroku.com/articles/github-integration
  70. 70. lanyrd.com/sdmbmk Automatic Deploys
  71. 71. lanyrd.com/sdmbmk Release Diffs
  72. 72. lanyrd.com/sdmbmk Heroku Button 1 click to a deployed Heroku app
  73. 73. lanyrd.com/sdmbmk app.json
  74. 74. lanyrd.com/sdmbmk README.md [![Deploy](https://www.herokucdn.com/deploy/button.png)] (https://heroku.com/deploy?template=https://github.com/ dgouldin/django-playground)
  75. 75. lanyrd.com/sdmbmk Try it yourself! github.com/dgouldin/django-playground
  76. 76. lanyrd.com/sdmbmk Bonus: Platform API devcenter.heroku.com/categories/platform-api
  77. 77. lanyrd.com/sdmbmk >>> import json >>> import requests # python-requests.org ! >>> heroku = requests.session() >>> heroku.auth = ('', '{INSERT HEROKU API TOKEN HERE}') >>> heroku.headers['Accept'] = 'application/vnd.heroku+json; version=3' >>> heroku.headers['Content-Type'] = 'application/json' REST API basics
  78. 78. lanyrd.com/sdmbmk >>> heroku.get('https://api.heroku.com/apps/happy-pycon-2015').json() {u'archived_at': None, ... u'web_url': u'http://dgouldin.herokuapp.com/'} ! >>> heroku.get('https://api.heroku.com/apps/happy-pycon-2015/config-vars').json() [35] : {u'NAME': u'David', u'REDISCLOUD_URL': u'{REDACTED}'} ! >>> body = json.dumps({'NAME': 'Robot'}) >>> heroku.patch('https://api.heroku.com/apps/happy-pycon-2015/config-vars', body) App info; config vars
  79. 79. lanyrd.com/sdmbmk >>> heroku.get('https://api.heroku.com/apps/happy-pycon-2015/formation').json() [{u'command': u'gunicorn hello:app', u'created_at': u'2015-04-06T16:42:24Z', u'id': u'928f6618-a0e2-4ded-95ec-e3a23a7795f0', u'quantity': 2, u'size': u'1X', u'type': u'web', u'updated_at': u'2015-04-06T18:50:02Z'}] ! >>> body = json.dumps({'quantity': 4}) >>> heroku.patch('https://api.heroku.com/apps/dgouldin/formation/web', body) Scaling
  80. 80. lanyrd.com/sdmbmk Questions and Free Play dgouldin@heroku.com @dgouldin

×