Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Heroku 102

Heroku 102

Rhys Elsmore

June 18, 2014
Tweet

More Decks by Rhys Elsmore

Other Decks in Programming

Transcript

  1. @rhyselsmore >>> import rhyselsmore Platform Security Engineer at Heroku. I

    focus on Anti-Abuse Systems. I develop using a mixture of Python/Go.
  2. @rhyselsmore Play & Scala & Clojure & Gradle & Grails

    & C & Common Lisp & Dart & Elixir & Erlang & Go & Haskell & JRuby & Lua & Perl & Rust & …
  3. @rhyselsmore Lets assume that You want to learn about Heroku


    You know (a bit) of Python
 You have Python, pip, and can create a virtualenv
  4. @rhyselsmore Lets assume that You want to learn about Heroku


    You know (a bit) of Python
 You have Python, pip, and can create a virtualenv install.python-guide.org
  5. @rhyselsmore $ heroku create Creating myapp... done, stack is cedar

    http://myapp.herokuapp.com/ | [email protected]:myapp.git Git remote heroku added
  6. @rhyselsmore $ cat .git/config [core] repositoryformatversion = 0 filemode =

    true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "heroku"] url = [email protected]:myapp.git fetch = +refs/heads/*:refs/remotes/heroku/*
  7. @rhyselsmore import os! from flask import Flask! ! app =

    Flask(__name__)! ! @app.route('/')! def index():! return "Hello, World!" heroku101.py
  8. @rhyselsmore $ git add .
 $ git commit -m ‘initial

    commit’ Store our changes in git
  9. @rhyselsmore $ git push heroku master ! -----> Python app

    detected -----> Preparing Python runtime (python-2.7.7) -----> Installing Setuptools (3.6) -----> Installing Pip (1.5.6) ! …. ! -----> Discovering process types Procfile declares types -> web ! -----> Compressing... done, 31.6MB -----> Launching... done, v3 http://myapp.herokuapp.com/ deployed to Heroku ! To [email protected]:myapp.git * [new branch] master -> master
  10. @rhyselsmore Runs processes concurrently locally via a Procfile Foreman Exposes

    a configuration to our processes Creates parity between production and development
  11. @rhyselsmore Runs processes concurrently locally via a Procfile Foreman Exposes

    a configuration to our processes Creates parity between production and development
  12. @rhyselsmore Runs processes concurrently locally via a Procfile Foreman Exposes

    a configuration to our processes Creates parity between production and development
  13. @rhyselsmore import os! from flask import Flask! ! app =

    Flask(__name__)! ! @app.route('/')! def index():! name = os.environ.get('PAGE_NAME', 'Rhys')! return "Hello, {0}!".format(name)! heroku101.py
  14. @rhyselsmore $ foreman start
 21:51:53 web.1 | started with pid

    20276 Launch your application locally. Did it work?
  15. @rhyselsmore $ git add heroku101.py
 $ git commit -m ‘loading

    name from configuration’
 $ git push heroku master … $ heroku open Commit our changes, and push to Heroku
  16. @rhyselsmore $ heroku releases
 === myapp v5 Set PAGE_NAME config

    vars [email protected] 2014/06/17 22:49:44 v4 Deploy 0b7df5b [email protected] 2014/06/17 22:49:33 v3 Deploy f6fc054 [email protected] 2014/06/17 22:00:32 v2 Enable Logplex [email protected] 2014/06/17 21:10:58 v1 Initial release [email protected] 2014/06/17 21:10:57 Viewing your Releases
  17. @rhyselsmore $ heroku rollback v4
 Rolling back myapp... done, v4

    ! Warning: rollback affects code and config vars; it doesn't add or remove addons. To undo, run: heroku rollback v5 Rolling back to another Release
  18. @rhyselsmore ! app ! redis Dev ! app ! redis

    Prod redis://my.production.redis redis://localhost
  19. @rhyselsmore import os! from flask import Flask! import redis! !

    app = Flask(__name__)! db = redis.from_url(os.environ.get('REDISCLOUD_URL'))! ! ! @app.route('/name/<name>')! def setname(name):! db.set('PAGE_NAME', name)! return "Name successfully updated"! ! ! @app.route('/')! def index():! name = db.get('PAGE_NAME') or "Rhys"! return "Hello, {0}!".format(name)! heroku101.py
  20. @rhyselsmore $heroku addons:add rediscloud Adding rediscloud on myapp... done, v7

    (free) Use `heroku addons:docs rediscloud` to view documentation. Add RedisCloud
  21. @rhyselsmore $ git add heroku101.py requirements.txt
 $ git commit -m

    ‘using redis as our db store’
 $ git push heroku master … $ heroku open Commit our changes, and push to Heroku
  22. @rhyselsmore 2014-06-17T16:03:07.702584+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=7be32154-cbca-4e9c-b235-2a86a204f32d fwd="50.31.252.204" dyno=web.1

    connect=1ms service=3ms status=200 bytes=172 2014-06-17T16:03:21.624306+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=180ee5c1-5c7e-4370-925c-4532bab44bb1 fwd="50.31.252.204" dyno=web.1 connect=1ms service=7ms status=200 bytes=172 2014-06-17T16:03:26.160610+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=71337d5d-ca00-49ed-98f6-e007123142de fwd="50.31.252.204" dyno=web.1 connect=0ms service=2ms status=200 bytes=172 2014-06-17T16:03:31.690643+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=b156826f-6db3-480d-bcc0-34239b2ad5a2 fwd="50.31.252.204" dyno=web.1 connect=1ms service=3ms status=200 bytes=172 2014-06-17T16:03:33.123754+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=a3768595-4fa5-41b7-aa2b-24ac4fa81880 fwd="50.31.252.204" dyno=web.1 connect=1ms service=3ms status=200 bytes=172 2014-06-17T16:03:34.186475+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=2e02b838-bdd6-47b2-b9c9-cd4d999ef1bc fwd="50.31.252.204" dyno=web.1 connect=0ms service=30ms status=200 bytes=172 2014-06-17T16:03:38.245823+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=c50b652a-1632-4727-b27a-03b0e89cdc4f fwd="50.31.252.204" dyno=web.1 connect=8ms service=30ms status=200 bytes=172 2014-06-17T16:03:48.101998+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.herokuapp.com request_id=94bd1cb4-446e-4309-9a67-94b210cdc3b2 fwd="50.31.252.204" dyno=web.1 connect=1ms service=2ms status=200 bytes=172 2014-06-17T16:03:49.663855+00:00 heroku[router]: at=info method=GET path="/" host=whispering-lake-5026.he
  23. @rhyselsmore import os! from flask import Flask! import log_metrics, random,

    time! ! app = Flask(__name__)! ! ! @app.route('/')! def index():! with log_metrics.timer('timed-function'):! time.sleep(random.uniform(0.5, 1.5))! log_metrics.increment('requests')! return "Hello, Librato!"! heroku101.py
  24. @rhyselsmore 00:18:20 web.1 | measure#timed-function.ms=1261.87 00:18:20 web.1 | count#requests=1 00:18:24

    web.1 | measure#timed-function.ms=925.83 00:18:24 web.1 | count#requests=1
  25. @rhyselsmore >>> import requests! >>> import json! ! >>> heroku

    = requests.session()! >>> heroku.auth = ('', '<my API token>')! >>> heroku.headers.update({! "Accept": "application/vnd.heroku+json; version=3",! "Content-Type": "application/json"! })! ! >>> heroku.get('/apps').json()! {! "id":49939049,! "name":"my-app-1",! "dynos":0,! "workers":0,! "repo_size":null,! "slug_size":null,! "stack":"cedar",! "requested_stack":null,
  26. @rhyselsmore >>> heroku.get('/apps/myapp/config-vars').json()! {! "NAME": "My App",! "SECRET_KEY": "hunter2"! }

    >>> heroku.patch(‘/apps/myapp/config-vars’, json.dumps({! ! "NAME": "My Apps new config var",! }))
  27. @rhyselsmore Further Questions… ! SSL Endpoints? File Storage? Multiple Languages?

    Free Limits? Does an add-on for $task exist? EU vs US region? Show us how to…