はじめに
こんにちわ!遅まきながらPython/Flask勉強中の石田です。FlaskをIBM CloudのPaaS(旧名Bluemix)で動かす際にいくつか注意点があったので、同じようなことをやろうとされる方のためにメモしておきます。
- ネット上に良記事が多数ありますので、Flask自身の説明は割愛します
- 記事執筆時点は2018/01です。将来的に変更があるかもしれません
- IBM CloudにデプロイするためのMinimalなHello World一式をここに置いておきますので、よろしければcloneしてご利用ください。(名前変更してbx cf pushすれば動きます)
FlaskをIBM Cloud(PaaS)上で動かす時の注意点・気が付いた点
① Cloudランタイムの作成
② ローカル環境(コード)の準備
③ Cloudへのデプロイ
の流れに沿って注意点や気が付いた点を記載します
1. Cloudランタイムの作成
ボイラープレートとランタイム
IBM CloudではPython FlaskのボイラープレートとPythonランタイムの2種類のメニューを提供しています。
最終的にはどちらでもいいのですが、Python Flaskのボイラープレートは
- ライトプランの対象なので、無料で使う分にはお勧めです
- Starter Codeのプログラム中では、Cloudantを利用していますが不要なら除去してしまいましょう
- 記事執筆時点、日本語コンソール(ブラウザーの言語設定が日本語)からはアプリの作成ができません。( Planの選択でエラーになり「作成」ボタンが押せない) この事象は英語コンソール(ブラウザーの言語設定を英語に変更)すれば解消します。( バグとして報告済なのですぐ直るでしょう)
デプロイされるStarter CodeはIBM-Cloud/get-started-pythonからダウンロードできます。
ランタイムのPythonバージョン
参考文献: Python
- Pythonのランタイムはデフォルトでバージョン 2.7.13 が選択されます。Python3を使いたい場合はruntime.txtにバージョンを記載します(後述)
2.ローカル環境での開発
コード
以下がIBM Cloud(cf)上にFlaskをデプロイするための最小限のhello worldコードです。
from flask import Flask
import os
import metrics_tracker_client
app = Flask(__name__)
metrics_tracker_client.track() # Trackingするなら必要
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
port = os.getenv('PORT', '5000') # portはIBM Cloud環境から割り当てられたものを利用
if __name__ == "__main__":
app.run(host='0.0.0.0', port=int(port), debug=True) # Procfile内でpython hello.pyで起動
以下の考慮点があります。
-
ポートはIBM Cloud(PaaS)環境から与えられる
世間一般のFlaskの入門記事などではappがListenするポート番号を明示指定したりデフォルト(5000)を使ったりしていますが、IBM Cloud/PaaS環境では、アプリは環境変数「PORT」から与えられるポート番号をListenする必要があります。インターネットなど外部からアプリにアクセスする場合は、PaaS側で標準の80/443ポートからアプリのListenしているポートへ自動的にルーティングしてくれますので、アクセスのURLにポート番号の指定は不要です。(逆に言うと上記の仕組みなので「勝手に使いたいポートを指定する」ことは基本、できません) -
Metrics Trackerのコードの追加
これは必須ではなく推奨オプションですが、アプリにMetrics Trackerを組み込んでおくとコンソール上の「monitoring」メニューで様々なモニタリングを行えるようになります。(逆に言うと、これを漏らすとモニタリングできません)
無料ですし、かなり色々な監視ができますので、IBM Cloud上で動かすなら使わない手はないでしょう。そのためにはコードに下記2行、追加しておいてください。
import metrics_tracker_client
metrics_tracker_client.track()
前述のPythonのStarter Codeではモニタリングのためにcf-deployment-trackerが使われていますが、これは2018年早々にも利用が停止されます(Deployment Tracker Service status)。モニタリングをするなら新しいmetrics-collector-serviceを使うようにしましょう。なお、これはPythonだけの話ではなくJavaやNodeなど他の言語でも同様です。(「Deployment Tracker Service status」の文書に移行の方針などが記載されています)
IBM Cloudにデプロイするためのファイル群
Pythonのコード(以下ではhello.py)以外に以下のファイルを用意します。
│ .cfignore ...① cf pushで除外したいディレクトリーやファイル
│ .gitignore
│ hello.py
│ manifest.yml ...② アプリ名やメモリ量の指定
│ Procfile ...③ 始動コマンド
│ README.md
│ requirements.txt ...④ Flaskなど利用するモジュールとバージョンを指定
│ runtime.txt ...⑤ 利用するPythonのバージョンを指定
│
└─__pycache__
hello.cpython-35.pyc
以下、指定例です。(Starter Codeにも含まれています)
.gitignore
---
applications:
- name: <<change-your-name>>
random-route: true
memory: 128M
web: python hello.py
Flask==0.12.2
metrics-tracker-client
python-3.6.2
3.IBM Cloudへのデプロイ
bx cf pushコマンド
ランタイムを定義して、上記のファイル群を準備したらあとはbx login
して
bx cf push
するだけで簡単にデプロイできます。実行中のメッセージは長いので掲載しませんが、途中でmanifest.ymlを選択してPythonのバージョンを選んでrequirements.txtを反映して、、という流れが見られます。デプロイのサーバー側の状況は別ウインドウで bx cf logs <アプリ名>
で見られます。
ご参考) Flaskアプリケーションの起動コマンドについて
Flaskアプリケーションを起動するコマンドは以下の2通りの方法があります
a) メインにしたいプログラムを直接指定する
python xxxx.py
b) 環境変数 FLASK_APPをセットしてからflask runコマンドを使用する
export FLASK_APP=xxxx.py
export FLASK_DEBUG=1
flask run
a) が昔からの方法でStarter Codeでも採用している/今までご紹介してきたものです。b) は最近の方法で、この場合は①環境変数を設定する②flask runコマンドを発行する など若干の変更を加える必要があります。以下、IBM Cloud上でflask runで起動する場合の方法を記載します。
【1】 flask runで起動する場合はプログラムの末尾のportの設定や__main__判定、app.runの部分は不要です。(書いても無視されます)flask runの場合のミニマムなコードは以下のようになります。
from flask import Flask
import os
import metrics_tracker_client
app = Flask(__name__)
metrics_tracker_client.track() # Trackingするなら必要
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
【2】manifest.ymlで環境変数 FLASK_APPをセットします(開発中はFLASK_DEBUGもセットするとよいでしょう)
---
applications:
- name: <<change-your-name>>
random-route: true
memory: 128M
env:
FLASK_APP: hello.py
FLASK_DEBUG: 1
【3】Procfileでflask runコマンドを実行します。--host 0.0.0.0で外部からのリクエストを受け付けます。ポート番号はOSの環境変数 $PORTをそのまま書けばよく、プログラム内で指定する必要は無くなります。(私の環境で試した際は8080が割り当てられていましたが、保証はありません)flask run --helpで他の設定可能なパラメータも見られます。
web: flask run --host 0.0.0.0 --port $PORT;
最終的にはpython xxx.py
でも flask run
でもそれなりの設定をすれば動くので問題ではありませんが、ネット上の記事やチュートリアルを見ていると、特に言及無くいずれかの方法で行っているものが多いです。IBM Cloudにデプロイする際は、前述のようにプログラムや設定に少し違いが出ますので、念のため両方の方法をお示ししました。
以上です。