経緯
週次で漫画の発売日をメールで送るpythonスクリプトをEC2の上で動かしていたりする。しかしawsの無料期間がすぎて地味に金がかかる。
そこで無料でできそうなherokuへの移設を試みてみた。いろいろやってみたことをまとめてみんとす。
1. herokuでのデプロイまでの簡単な流れ
### heroku環境準備(centos前提)
## heroku toolbeltをインストール
$ sudo wget -qO- https://toolbelt.heroku.com/install.sh | sh
$ sudo ln -s /usr/local/heroku/bin/heroku /usr/local/bin/heroku
## herokuコマンド実行確認
$ heroku version
heroku-toolbelt/3.32.0 (x86_64-linux) ruby/2.0.0
You have no installed plugins.
## 認証
$ heroku login
Enter your Heroku credentials.
Email: hoge@mail.com
Password (typing will be hidden):
Authentication successful.
### APP準備
$ cd myAPP
# pipでライブラリインストール
# viなりでコード書く
# テストしたり
$ git init
$ git add .
$ git commit -m "my first commit"
### herokuにデプロイ
## APP登録
$ heroku create
# ここらへんはheroku create myAPPのが素直な気がしないでもない
# そうしないとAPPの名前はheroku上で適当につけられる
## 必要なモジュールを明記
$ pip freeze > requirements.txt
$ git add requirements.txt
$ git commit requirements.txt
## デプロイ
$ git push heroku master
## ログみる
$ heroku logs -t
ここら辺はherokuに載っているgetting startをひと通り試してだいたいわかった。
centos嫌いなんか、toolbeltのインストールは公式からたどるとdebian系しか書いてなくて、standaloneから入れるんね...と。
参考:
Getting Started with Python on Heroku | Heroku Dev Center
[vagrant 1.5] Vagrant 上の CentOS 6.5 から Heroku を使うには。 - Qiita
2. herokuで内緒な情報を環境変数登録してデプロイ
# それぞれsetして
$ heroku config:set SENDGRID_USER_ID="hogehoge"
$ heroku config:set SENDGRID_PASS="fugafuga"
$ heroku config:set TO_ADDRESS="hoge@mail.com"
$ heroku config:set FROM_ADDRESS="fuga@mail.com"
# 確認
$ heroku config
=== hogehoge Config Vars
FROM_ADDRESS: fuga@mail.com
SENDGRID_PASS: fugafuga
SENDGRID_USER_ID: hogehoge
TO_ADDRESS: hoge@mail.com
とやって、例えば
import os
print os.environ["SENDGRID_USER_ID"]
とするとAPPごとの環境変数を設定できる。
これはherokuのweb画面からも設定できる。(その場合もlocalからすぐ参照できる)
herokuはgit経由でデプロイするが、git.heroku.comが公開されてるような?or github接続でデプロイする場合にはコードを公開されたりするのでメールアドレスやパスなど隠したい。
そこでアプリに紐づく環境変数をcli or webから設定すると秘匿してくれるのでやってみた。
*1 githubに金を払ってプライベートレポジトリを使えという話もある
*2 heroku toolbeltというcliコマンドがローカルにインストールされてる前提です
もっと適切は方法があるような気がしたが一旦heroku toolbeltが入るなら、localテストも特に問題なさそうなのでこれで。
3. sendgrid経由でメールを送るpythonスクリプト
pipでsendgridいれて、ほぼほぼのチュートリアル通り。
ただ、上記の環境変数を利用するための若干変更して以下のようになる。
import sendgrid
import os
sg = sendgrid.SendGridClient(os.environ["SENDGRID_USER_ID"], os.environ["SENDGRID_PASS"])
message = sendgrid.Mail()
message.add_to(os.environ["TO_ADDRESS"])
message.set_from(os.environ["FROM_ADDRESS"])
message.set_subject("Sending with SendGrid is Fun")
message.set_html("and easy to do anywhere, even with Python")
sg.send(message)
なお、heroku公式っぽいこっちのチュートリアルを見ると、api_keyとかapi_userとかある。まるでapiのtokenを発行しないといけないっぽい。 が、実際にはsendgridのログイン時に用いるアカウントのidとpassでよかったので紛らわしかった。
あとsendgridってアカウント作るのに数日かかったので事前に準備しとかないとすぐぱぱっとできないなと。
参考:
sendgrid/sendgrid-python
Python - SendGrid Documentation | SendGrid
*下の方のリンクに釣られた
4. heroku schedulerでcron的に実行
ひと通りデプロイしてheroku 上での動作確認がすんだら、
$ heroku run python sg_test.py
heroku schedulerのアドオンを追加する。
$ heroku addons:add scheduler:standard
*ちなみにアドオンには無料枠があるがそれを超えると有料なのでクレカ情報を事前にherokuに登録必要がある。
あとは動作確認にlogなど眺めていればよい。
ちなみに、heroku schedulerを入れる途中でいろいろやっててprocess schedulerも登録されちゃってたり。こっちはリソース管理を1週間の中で1時間単位でHerokuのリソースセットを変えられるもののよう。カレンダーなGUIがあるので、むしろheroku schedulerでこの設定がまとめてできればと...
参考:
Heroku Scheduler | Add-ons | Heroku
Heroku Scheduler | Heroku Dev Center
heroku schedulerの使い方(Rails,sinatra) - Qiita
まとめ
表題の件は実装できはした... しかし、やりたかったのは週次でのバッチでメールを送ることなので結局やりたいことはできず...
(途中で気づいたけど遊んでみたというか軽くherokuを触ってみたかった)
heroku scheduerは10分ごと、毎時、毎日、しか設定できなかった... APP側でそういうlogicをいれれば解消できるがそれもなんかなー、と。 また場合によってはpaasあるあるで1時間アクセスないとプロセスがsleepしてしまったりで、定期的にcurlでつつくやつとか必要になったりでなんか不毛に...
結局むりくり無料にこだわるよりも、digital oceanあたりに月500円でVMを1つ建てたほうが気軽な気はした。 paasだと結局ローカル/リモートのテストと実行時の問題が難しいなとしみじみした。
バッチ用というかcron実行に特化したpaasってどこかないのかな?たぶんあるんだろうけど探せて無い気がする。
ちなみにdockerコンテナ作ってそれをwebにあげるDokku alternativeなるpaas?があるらしいのでそっちだと願いは叶えられそうな気はした。ただそれはもうpaasなのか?というのと、これは自前でpaasをつくろうな話であるなと。。
参考:Herokuのように簡単に使えるDockerベースのPaaS | KRAY Inc
以上。