自分用メモ
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 start
や pg_ctl stop
で起動・停止できる。
(普通だと postgres -D /usr/local/var/postgres
とからしいので面倒)
最初からあるpostgresユーザで入ってみたり、データベース一覧を表示したりして確認
psql -l # DB表示
psql postgres # postgresユーザでログイン(出るときは \q)
Heroku にアカウント作成
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 config
のDATABASE_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情報ポータル。