はじめに
本記事は爆速(1日)でHerokuに幼稚園児並みのアプリをデプロイしていくまでの軌跡である。
Herokuへのデプロイの仕方が主で、Flaskについては幼稚園児並みにしか触れないので注意されたい。
環境
動作OS:Windows10 home
ターミナル:Powershell
言語:Python 3
実施手順
venvでの環境構築
任意のディレクトリに任意名のフォルダを作成する。
kindergartenというのは幼稚園という意味である。
幼稚園児でも理解できる記事にしていきたいと思う。
$ mkdir flask_kindergarten
$ cd flask_kindergarten
pythonでvenvを実行しアクティベートしていく。
WindowsやMac、Linuxでコマンドに差分があるので注意。
ターミナルがPowershellかCOMかでも差分があるので注意。
今回はWindows-Powershellでの実行だが環境差分がある人は、当該環境でvenvアクティベートの仕方を調べると良いだろう。
$ python3 -m venv venv
$ Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
$ venv/Scripts/Activate.ps1
Flaskのインストール。
$ python3 -m pip install Flask==1.1.2
herokuへデプロイする用のrequirements.txtを作成。venvは仮想環境ごとにpipのスコープを持つので仮想環境下でインストールしたものだけがテキストファイルに出力される。
$ python3 -m pip freeze > requirements.txt
次に、お待ちかねFlaskのメインのコードを書いていく。
MVCモデルで言うところのC=Controllerにあたり、アプリの背骨の部分である。
現在のディレクトリにapp.pyを作成。
$ type nul > app.py
今のディレクトリ構成はこんな感じ。
flask_kindergerten/
│
├── venv/
│
├── app.py
└── requirements.txt
では、app.pyを記述して一度Flaskを立ち上げていこう。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "お前、どこ園だ、バブゥ!?"
$ flask run
ローカルで立ち上がったWebサーバを覗きに行く。デフォルトでは127.0.0.1:5000/であった。
ブラウザに遷移して「お前、どこ園だ、バブゥ!?」と表示されていたら勝ちである。
これは不良中学生の「お前、どこ中だ、オラァ!?」のオマージュである。
コードに変更があった場合にいちいちWebサーバを落として再起動しなくても済むように以下のコマンドを打っておく。
例によって、環境差分があるので注意。
$ $env:FLASK_ENV = 'development'
次に、herokuにデプロイするためにgitの設定をしていく。
'git init'でレポジトリの初期化を行ったあとに'.gitignore'でコミットしないファイルを指定する。.gitignoreはvenvや__pycache__のほかにSECRET KEYを書いたconfigファイルとかを指定する場合があると思う。
また、'>'
この大なりの記号は出力リダイレクトといって出力結果をリダイレクト先に書き込むことができる。
'>>'で追記となる。
$ git init
$ echo venv > .gitignore
$ echo __pycache__ >> .gitignore
$ git add .gitignore app.py requirements.txt
$ git commit -m "my first commit"
Herokuへのデプロイ
まず、Herokuに未登録の人はこちらから登録しよう。
次に、CLIを使うためにこちらからインストールしよう。
ここまでできたらHerokuにログインしよう。
$ heroku login
次に、Herokuにデプロイする準備をする。
まずはHerokuの設定ファイル'Procfile'を作成していく。
このProcfileだが、間違えると痛手になる。
具体的には以下2つには気をつけて欲しい。私はこれに2時間くらい足踏みし、結果として爆速味が失われてしまった。
- 最初のPは必ず大文字にすること
- UTF-8でエンコードしていること
以下のようにProcfileを作成する。
web: gunicorn app:app
次に、PythonのWSGIであるgunicornをインストールする。
WSGIとはWeb Server Gateway Interfaceの略であり、アプリとサーバの差分をなくして標準化するようなインターフェースだそうだ。
$ python3 -m pip install gunicorn==20.0.4
$ python3 -m pip freeze > requirements.txt
gunicornをインストールしたので、requirements.txtを更新した。
では、追加分をgitに反映する。
$ git add Procfile requirements.txt
$ git commit -m "Add Heroku deployment files"
Herokuにリポジトリを作成して、git pushしていく。
いつもは'origin'でpushしてるところは'heroku'に変更になるから注意だ。
あと、Herokuはアンダーバーが使用不能なのでリポジトリ名をハイフンで代用する。
$ heroku create flask-kindergarten
$ git push heroku master
がんばってクラウド上のサーバでデプロイしてまっせ、みたいなメッセージ群が流れ終わったら完了だ。
では、実際に確認してみよう。
$ heroku open
Herokuのドメインで先の幼稚園児アプリが確認できたらOKだ!
パイプラインの実装
Herokuへのデプロイまでなら前項で終了なのだが、それだとあまりに幼稚園児すぎるので、せめて小学生に顔向けできるように最後にパイプラインを構築する。
パイプラインというのは複数の環境をワークフローで結んだグループのことである。
複数の環境というのは、主に開発環境・ステージング環境・本番環境のことである。
ここまでで使用した環境はローカルの開発環境とHerokuの本番環境だけだが、これだと実運用では困るだろう。
例えば、往々にして開発環境と本番環境には環境差がある。
開発環境ではうまく作動した機能が本番環境でもうまく作動するかわからない。なんなら、機能追加してしまったせいで本番環境がうまく動作しなくなるなんてこともあるだろう。
そんな時に役立つのがステージング環境である。
ステージング環境は本番環境と同様の環境をつくり、ここで新機能などのテストを行うのだ。
各環境のイメージは以下。
これらを結ぶものがワークフローであり、ワークフローによってグループ化されたものがパイプラインだ。
それでは、早速ステージング環境をHerokuに構築していこう。
$ heroku create flask-kindergarten-staging --remote staging
$ git push staging master
https://flask-kindergarten-staging.herokuapp.com/
みたいな名前で本番環境と同じものが確認できればOKだ!
では、次にパイプラインを作成していく。
flask-pipelineというパイプラインに本番環境としてflask-kindergartenのアプリを登録する。
$ heroku pipelines:create --app flask-kindergarten `
--stage production `
flask-pipeline
次に、gitを反映させる。
gitでの名前はprodとする。
$ heroku git:remote --app flask-kindergarten --remote prod
そして、ステージング環境としてflask-kindergarten-stagingのアプリをパイプラインに加えていく。
$ heroku pipelines:add flask-pipeline \
--app flask-kindergarten-staging \
--stage staging
では、先ほどのapp.pyの中身を少し変更し、ステージング環境だけに反映してみよう。
from flask import Flask
# make app instance
app = Flask(__name__)
# routing
@app.route('/')
def index():
return 'あなた様はどこ園かしら?'
なんとなく女子にしてみた。
それでは、ステージング環境にファイルをcommitしていく。
$ git add app.py
$ git commit -m "changed"
$ git push staging master
ブラウザでステージング環境と本番環境のURLを叩いて、別々の表示になっていればOKだ。
最後に、ステージング環境の変更を本番環境へパイプラインを用いて反映させる。
$ heroku pipelines:promote --remote staging
本番環境にも変更が反映されていれば完了だ!
おわりに
今回は爆速でFlaskアプリをHerokuにデプロイしたわけだが、Flaskアプリ部分があまりにも幼並完(幼稚園児並みの完成度)であった。
今度はちゃんとHTMLなりを実装し、まともなFlaskアプリを構築してみようと思う。
ではまた!