Help us understand the problem. What is going on with this article?

heroku で python 動かすチュートリアルをやったメモ

More than 3 years have passed since last update.

自分用メモ

HerokuのPythonチュートリアルをやりました。
https://devcenter.heroku.com/articles/getting-started-with-python
メモ用と思って残しましたが特につまづかなかったので、ノウハウ的なものではなくコマンドメモになりました。

前提

ローカルで python は動いてる
virtualenv もある

macにpostgresqlをインストール

brew intall postgresql

postgres用に設定

echo 'export PGDATA=/usr/local/var/postgres' >> ~/.zshrc # それぞれのprofileに

これで pg_ctl startpg_ctl stop で起動・停止できる。
(普通だと postgres -D /usr/local/var/postgres とからしいので面倒)
最初からあるpostgresユーザで入ってみたり、データベース一覧を表示したりして確認

psql -l # DB表示
psql postgres # postgresユーザでログイン(出るときは \q)

Heroku にアカウント作成

https://www.heroku.com/

Heroku用CLIツールをインストール

brew install heroku-toolbelt

その後 Heroku にログイン

$ heroku login
Enter your Heroku credentials.
Email: [email]
Password (typing will be hidden):
Logged in as [email]

サンプル app の用意から deploy まで

サンプルアプリをcloneする。

git clone https://github.com/heroku/python-getting-started.git
$ cd python-getting-started

できたら、Herokuにアプリを登録する

$ heroku create
Creating morning-plateau-xxxx... done, stack is cedar-14
https://morning-plateau-xxxx.herokuapp.com/ | https://git.heroku.com/morning-plateau-xxxx.git
Git remote heroku added

適当な名前(今回はmorning-plateau-xxxx)でアプリが登録される。
名前を付けたい場合は create の後ろにかく。 heroku create sanmple-name-app
この時点でローカルの git に heroku という名前で remote が登録される。
URLにアクセスすると初期ページみたいなのが出た。

初期ページっぽいの

次に、サンプルアプリを deploy する

$ git push heroku master
Counting objects: 185, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (91/91), done.
Writing objects: 100% (185/185), 30.52 KiB | 0 bytes/s, done.
Total 185 (delta 80), reused 185 (delta 80)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing runtime (python-2.7.9)
remote: -----> Installing dependencies with pip
# 長いので省略
remote: -----> Compressing... done, 42.9MB
remote: -----> Launching... done, v4
remote:        https://morning-plateau-xxxx.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.

deploy完了。
出力を見ると、単にpushするだけでなく、何やら環境構築したりコマンド実行されていることが分かる。

アプリを動かすためのプロセスを下記コマンドで起動する。
scaleを1に指定しているが、大きくするとお金かかるんだろうか?
とりあえず動かすために、"Ensure that at least one instance of the app is running"とのこと。

$ heroku ps:scale web=1
Scaling dynos... done, now running web at 1:Free.

ps コマンドを実行すると確かに動いているようだ。

$ heroku ps
=== web (Free): gunicorn gettingstarted.wsgi --log-file -
web.1: up 2016/01/06 02:36:49 (~ 8m ago)

ちなみにweb=2にするとこうなった。うーん。(あとでしらべる)

$ heroku ps:scale web=2
Scaling dynos... failed
 !    Cannot update to more than 1 Free size dynos per process type.

最後に、下記でアプリを開く

heroku open

簡単。ここでとりあえずページを開くところまで完了。

ログを見る

heroku logs
heroku logs --tail # tail で見れる

Procfile?

アプリケーションのrootディレクトリにあるテキストファイルで、アプリケーションの立ち上げに必要なコマンドを書く。
PythonのサンプルアプリケーションのProcfileは下記のようになっていた。

web: gunicorn gettingstarted.wsgi --log-file -

web がプロセスタイプで、その後がコマンド。
普通に起動すると一つのdynoでプロセスが走る。
(dynoって? ここではProcfileのコマンドを走らせる軽量コンテナ)
ちゃんとみたい場合は heroku ps

デフォルトではdynoは1つ&freeで、30分アクセスがないor一日18時間以上動くととスリープモードに入る。
18時間以内ならアクセスが来ると毎回立ち上がるが、スリープ後だと立ち上げ処理入るので若干重い。
スリープがいやorスケールしたい場合はProfessionalに変えてねとのこと。

アプリの依存関係

requirements.txt が root ディレクトリにあれば、Herokuはpython appであると認識するようだ。
サンプルアプリの requirements.txt の中身は次のようになっている。

$ cat requirements.txt
dj-database-url==0.3.0
Django==1.8.1
django-postgrespool==0.3.0
gunicorn==19.3.0
psycopg2==2.6
SQLAlchemy==1.0.4
whitenoise==1.0.6

チュートリアルにのっていたものと若干違うが、Herokuはこれを元に必要なライブラリをインストールする。
これは御存知の通り pip freeze と同じ形式。
ダウンロードしてきたサンプルアプリなので、とりあえず同じ環境をローカルに作る。
pythonのバージョンは、ルートディレクトリにある runtime.txt に書いてある。
(pyenvを使っていたためそれで環境作成した。)

$ cat runtime.txt
python-2.7.9
$ pyenv install 2.7.9
$ pyenv virtualenv 2.7.9 sample-app
$ cd [workspace]
$ pyenv local sample-app
$ pip install -r requirements.txt --allow-all-external

ローカルで動かす

herokuで動かしたものをローカルでも動かす。

$ python manage.py collectstatic # プロジェクト内の静的ファイルを一箇所に集める
$ heroku local web

http://localhost:5000/ にアクセスして確かに動いていることを確認。

ローカルの変更を heroku に反映

適当にローカルを変更してherokuにpushする流れ。requestsをimportして、適当なサイトにリクエストを飛ばしてそのレスポンスを表示するような変更を加えて、pushしている。
まず、requirements.txt に次を加える。

requests==2.3.0

hello/views.py の頭に次を足し、

import requests

indexという関数を次のように書き換える

def index(request):
    r = requests.get('http://httpbin.org/status/418')
    print r.text
    return HttpResponse('<pre>' + r.text + '</pre>')

ローカルで実行

$ pip install -r requirements.txt --allow-all-external
$ heroku local

http://localhost:5000/ にいってみると、、http://httpbin.org/status/418 の内容が。

    -=[ teapot ]=-

       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`

かわいい。

無事変わっていたので、herokuに反映させる。

$ git add .
$ git commit -m "Demo"
$ git push heroku masterg
$ heroku open

deploy完了、同じteapotのページが開く。
herokuへのdeployは基本的にこの流れ。

アドオンの追加

例として、papertrailを追加する。

$ heroku addons:create papertrail
 !    Please verify your account to install this add-on plan (please enter a credit card) For more information, see https://devcenter.heroku.com/categories/billing Verify now at https://heroku.com/verify

怒られた。悪用防止のためaddonはverifyがいるようだ。
びびりつつクレカ情報を登録して再度試すといけた。

$ heroku addons:create papertrail
Creating papertrail-rigid-xxxx... done, (free)
Adding papertrail-rigid-xxxx to morning-plateau-xxxx... done
Setting PAPERTRAIL_API_TOKEN and restarting morning-plateau-xxxx... done, v6
Welcome to Papertrail. Questions and ideas are welcome (support@papertrailapp.com). Happy logging!
Use `heroku addons:docs papertrail` to view documentation.

これでdeployed. 現在のaddon一覧は下記コマンドで見れる。

$ heroku addons
Add-on                                         Plan       Price
─────────────────────────────────────────────  ─────────  ─────
heroku-postgresql (postgresql-octagonal-xxxx)  hobby-dev  free
 └─ as DATABASE

papertrail (papertrail-rigid-xxxx)             choklad    free
 └─ as PAPERTRAIL

The table above shows add-ons and the attachments to the current app (morning-plateau-xxxx) or other apps.

papertrail で早速見てみる

heroku addons:open papertrail

ブラウザが開いてログが確認できる。

コンソール

heroku run COMMAND コマンドでherokuのコンソールが使える。
ここではコマンドはone-off dynoという一時的なdyno上で動いているらしい。

$ heroku run pwd
Running pwd on morning-plateau-xxxx... up, run.5945
/app
$ heroku run python manage.py shell
Running python manage.py shell on morning-plateau-xxxx... up, run.4047
Python 2.7.9 (default, Dec 11 2014, 17:18:51)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import requests
>>> print requests.get('http://httpbin.org/status/418').text

    -=[ teapot ]=-

       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`

同様に、dynoのbashを下記で動かせる。

$ heroku run bash
Running bash on morning-plateau-xxxx... up, run.3252
$ ls
app.json  gettingstarted  hello  manage.py  Procfile  Procfile.windows  README.md  requirements.txt  runtime.txt  staticfiles
$ exit
exit

設定用変数の定義

外部に置きたい secret key のような設定用変数や外部リソース。

実行時、設定変数は環境変数に入る。

hello/view.py の最初に次を追加。

import os

また、indexを次のように書き換える

def index(request):
    times = int(os.environ.get('TIMES',3))
    return HttpResponse('Hello! ' * times)

local の .env ファイルに次を追加。ここを見て環境変数が設定される。

TIMES=2

heroku config:setでもHeroku上での設定変数を設定できる。またheroku configで確認できる。

$ heroku config:set TIMES=2
Setting config vars and restarting morning-plateau-xxxx... done
TIMES: 2
$ heroku config
=== morning-plateau-xxxx Config Vars
DATABASE_URL:         xxxx
PAPERTRAIL_API_TOKEN: xxxx
TIMES:                2

データベースの準備(FreeのPostgresアドオン)

データベースもaddonで色々用意されている。addonなので現在のものをheroku addonsで確認できる。
heroku configDATABASE_URLで、接続先データベースのURLが登録されているのが見れる。

heroku config
=== morning-plateau-xxxx Config Vars
DATABASE_URL: postgres://~~~ #略

また、heroku pg コマンドは詳細が得られる。

$ heroku pg
=== DATABASE_URL
Plan:        Hobby-dev
Status:      Available
Connections: 0/20
PG Version:  9.4.4
Created:     2016-01-05 17:36 UTC
Data Size:   6.4 MB
Tables:      0
Rows:        0/10000 (In compliance)
Fork/Follow: Unsupported
Rollback:    Unsupported
Add-on:      postgresql-octagonal-xxxx

サンプルプロジェクトにもDBは既に有効化されていて、URL末尾に /db とつけることでアクセスできるが、今の状態ではまだテーブルが作成されていないため、アクセスするとエラーになる。
djangoでテーブルを作るために、Herokuでmanage.py migrateを実行する。

$ heroku run python manage.py migrate
Running python manage.py migrate on morning-plateau-xxxx... up, run.6683
Operations to perform:
  Synchronize unmigrated apps: messages, hello, staticfiles
  Apply all migrations: admin, sessions, auth, contenttypes
  # ...
  # 略

もう一度URL+/dbにアクセスすると、今度はエラーではなく、アクセスする度にレコードが増えていくようなシンプルなページが表示される。

DBのモデルはhello/models.pyに、設定はgettingstarted/settings.pyにある。
(djangoについての説明はしません)

ローカルにpostgresqlがはいっているなら、プロジェクトのrootディレクトリからherokuのdbに次でアクセスできる。

$ heroku pg:psql
---> Connecting to DATABASE_URL
psql (9.4.5, server 9.4.4)
Type "help" for help.

morning-plateau-xxxx::DATABASE=> select * from hello_greeting;
 id |             when
----+-------------------------------
  1 | 2016-01-11 16:09:35.860529+00
  2 | 2016-01-11 16:10:28.385479+00
(2 rows)

Heroku Postgres の詳細については https://devcenter.heroku.com/articles/heroku-postgresql を参照とのこと。

次のステップ

ここまででチュートリアルは終わり。最後に、次のステップとして2つのリンクが用意されている。
- How Heroku Works https://devcenter.heroku.com/articles/how-heroku-works
Heroku自体についての詳細知りたい人向けリンク。
- Python on Heroku https://devcenter.heroku.com/categories/python
Heroku内のPython情報ポータル。

cfiken
自分の理解のためのアウトプットをよく投稿しています。よろしくおねがいします。 Twitter: https://twitter.com/cfiken
mixi
全ての人に心地よいつながりを
http://mixi.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした