[heroku]DockerとherokuとCircleCIでアプリをらくらくデプロイ


概要

dockerでflaskアプリを作成しherokuへアップロードした後、circleciを使ってはじめのアップデート後の自動デプロイまでを実装したのでその方法をまとめる。おそらくflask以外のアプリでもこの方法で自動デプロイまでできるのでさんこうまでに。

仕様

技術 バージョン
Docker 20.10.2
docker-compose 1.27.4

流れ

herokuのdockerでのデプロイの流れは以下のようになる。

①herokuのログイン

②herokuのアプリ作成

③herokuとgitの紐付け

④herokuへdockerコンテナをpush

⑤herokuでdockerコンテナを起動する

⑥herokuでアプリの確認

⑦herokuのログの確認

⑧herokuのサーバーの停止と再起動

⑨herokuのapikeyの作成 ←CircleCIに必要なため

※前提として全てアプリのディレクトリ内を想定している。

①herokuのログイン

herokuへのログインは以下のコマンドを叩く。
container:loginはdockerを起動するために必要なので必ず両方のコマンドをしなければならない。

terminal
# herokuへのログイン
heorku login

heroku  container:login

②herokuのアプリ作成

次にherokuで作成するアプリの名前を決める。
※マイナーな名前にしないと既に使われているとか言われてエラーになるので注意

terminal
# app名に自分の付けたいアプリの名前を入れる
heroku create app名

③herokuとgitの紐付け

gitとherokuを連携するために以下のコマンドを叩く。
app名には②で指定したapp名をいれる。

terminal
heroku git:remote -a app名

④herokuへdockerコンテナをpush

herokuへdockerのコンテナをデプロイするために以下のコマンドを叩く。
コンテナの立ち上げをするためここは時間がかかる。
ここでデプロイされるのはdocker-composeなので注意する。

heroku container:push web

※注意
webの部分がdocker-composeのserviceで付けた名前のことだと思ってappとしていてずっとエラーで詰まっていた。結論としてはwebがbackendを表示させるためのdefaultの設定らしいので変更できないとのこと。

⑤herokuでdockerコンテナを起動する

ついにherokuでコンテナを起動する。

terminal
heroku container:release web

⑥herokuでアプリの確認

以下のコマンドで実際にアプリが立ち上がってるページへ転移することが出来る。

terminal
heroku open

⑦herokuのログの確認

⑥でAppliaction Errorが起きた際などにどのようなエラーが起きていたか、backendの処理がきちんとできているか以下のコマンドでlogを確認することが出来る。

terminal
heroku logs --tail

⑧herokuのサーバーの停止と再起動

サーバーの片付けと再起動は以下のコマンドを叩く。
web=0or1で管理できるのは非常に簡易的だ。

terminal
#サーバーの停止
heroku ps:scale web=0

#サーバーの再起動
heroku ps:scale web=1

以下のコマンドでサーバーが起動しているかどうか確認できる。

terminal
heroku ps

⑨herokuのapikeyの作成

以下のコマンドでapikeyが作成できる。

heroku authorizations:create

つまづいたところ

以下のエラーでつまづいた。

Web process failed to bind to $PORT within 60 seconds of launch

Web process failed to bind to $PORT within 60 seconds of launch

stackoverflowの回答によると、herokuでは動的にポートが割り当てられるためポートに固定値を設定しようとしたために起きたエラーとのこと。
そのため、私の場合flaskのapp.runの部分を以下のように書き直した。
このように記述することで環境変数からポートを見た後に、ない場合に5000番ポートへルーティングするような処理にすることが出来る。

app.py
#before
app.run(debug=True, host='0.0.0.0',
            port='5000')

#after
app.run(debug=True, host='0.0.0.0',
            port=int(os.environ.get('PORT', 5000)))

CircleCIによる自動デプロイ

CircleCIの自動デプロイには位置からworkflowを作成するのではなく、CircleCI Orbsを使用した。

CIrcleCI Orbsはherokuで言えば、herokuへのログインやherokuへのコンテナのpushなどあらかじめ必要な動作を一連のまとめとして使い回せるようにしたもので、Orbsを使用することで簡単にCircleCIのherokuの自動デプロイを達成することが出来る。

CircleCIのせっていの流れは以下のようになる。

①CircleCIの公式サイトよりsetupをする

②CircleCI Orbsよりherokuのデプロイに使用できそうなorbsを探す

③.circleci/config.ymlの作成

④CircleCIの環境変数の設定

⑤githubのリポジトリへpushする

①CircleCIの公式サイトよりsetupをする

まずCircleCIの公式サイトにGithubと連携してログインを済ませる。すると、サイドバーからProjectを選択でき、以下の写真の様な画面になるのでSet Up Projectを押してsetupを開始する。
Unfollw ProjectはすでにCircleCIの設定が完了しているProjectである。

そして以下の画面の中心部分にある青いボタンのCommit and Runを押してsetupを完了する。
※はじめにサンプルのciが起動するが気にしなくて良い。

②CircleCI Orbsよりherokuのデプロイに使用できそうなorbsを探す

CircleCIの検索ページへ行き、heroku dockerなどの検索ワードで使用できそうなorbsを探す。

今回私は、pbrisbin/[email protected]を使用した。

JobsとCommandsの部分で自分で設定しなければならない。
今回使用するorbsでは以下の写真のようにapp-nameがひつようなのがわかる。

✅となっている部分が自分で設定しなければならない変数となっている。

また、自分でProjectに設定しなければならない環境変数がある。
環境変数については何が必要かわかりづらいもので注意が必要。
今回は以下のようにloginでHEROKU_EMAILとHEROKU_API_KEYが必要なのがわかる。

Environment variableでページ内検索すると分かる可能性があるので ⌘+F でEnvironment variableで検索するのが良いだろう。

③.circleci/config.ymlの作成

CircleCIはgithubリポジトリの.circleci/config.ymlをもとに実行されるので作成する。
まず以下のコマンドで.circleci/config.ymlを作成する。

terminal
mkdir .circleci
touch .circleci/config.yml

次に以下のようにconfig.ymlを記述する。
※ version2.1以上でないとorbsが使えないので注意
これでmasterブランチへpushされたときにherokuへ自動デプロイが実行される。

version: 2.1
orbs:
  heroku-container: pbrisbin/[email protected]
workflows:
  build_and_release:
    jobs:
      - heroku-container/push-and-release:
          app-name: herokuの②で設定したapp名
          # masterブランチへのpushでのみ反応
          filters:
                branches:
                    only:
                    - master

④CircleCIの環境変数の設定

CircleCIの②で述べたようにHEROKU_EMAILとHEROKU_API_KEYという環境変数が必要になるのでProjectのページに移動し以下の画像の右上のProject Settings→Environment Variables→Add Environment Variablesより環境変数を設定する。
※apikeyはherokuの⑨で作成したものを利用する。

⑤githubのリポジトリへpushする

最後にgithubのリポジトリにpushしてCircleCIのProjectより起動しているか確認します。
以下のようにSuccessになっていれば大丈夫です。

つまったところ

To use this orb, an organization admin must opt-in to using third party orbs in Organization Security settings.

以下のエラーはorbsが使える設定になっていないために起こっている。

そのため、以下の手順をふむ。
Dashboard → Organization Settings → Security → Orb Security SettingsをYesに変更

これでorbsが使えるようになる。

参考文献

Heroku + node.js error (Web process failed to bind to $PORT within 60 seconds of launch)

Orbsの概要

pbrisbin/[email protected]

CircleCIの検索ページ