本日、かしゆかの誕生日です、どうぞみなさまお祝いください。
さて、本日の内容です。
Container Registry が GA になったよ!!
2017/9/5 の changelog で Container Registry GA - Deploy Docker images to Herokuと公開されたとおり、これまでβサービスとして提供されていた Docker 向けコンテナサービスが、本番向けにリリースされました。
これまで buildpack の制約や、docker でせっかく準備した開発サイクルのために、Herokuの利用を躊躇されていたみなさまには、朗報です。はやいところ、Heroku Pipelines 上で Heroku CI つかって、Docker のCI/CD まわしたいですね!! Heroku は世界を支配しますよ!!
(もしかすると、https://devcenter.heroku.com/articles/heroku-yml-build-manifest これ使うと、Pipelines も Review Apps もいけるかもしれないんですが、いまテスト中です。ややこい)
とは言え、Docker完全サポートではありません。Dockerで動きさえすればHeroku上でも動く、というわけでは残念ながらありません。Docker を Heroku上で動かすためには、いくつかの注意事項がありますので、そちらをご紹介します。
前提条件
Docker を Heroku上で動かすためには、最低限の条件が3点あります。
- Heroku アカウントを持っていること
- Heroku CLI コマンドを導入して、利用可能にしていること
- docker コマンドを導入して、利用可能なこと
現時点では、Dockerイメージを Heroku 上にデプロイするためには CLIが必須です。また、ローカルでdockerコマンドを実行して制御するため、Docker コマンドが必須です。Docker 使おうってんだから、みんな入ってるはずですけど。
デプロイの流れとコマンド
実際に、ローカルに準備した Dockerfile
をHeroku上へデプロイする場合の流れは、次のとおりになります。すべて、コマンドで実行した場合です。一部、GUIでも実行可能な部分については、その旨を追記しています。
-
heroku login
で、Heroku アカウントへログインさせます。 -
heroku container:login
で、Heroku 上の Container Registry へログインします。 -
heroku create
で、Docker を動かすための Herokuアプリを作成します(GUIでも可)。 -
heroku addons:create
で、必要なアドオンを追加します(GUIでも可、アドオン不要なら実行不要)。 -
heroku container:push <process-type>
で、ローカルの Dockerfile もろもろをデプロイします。 - docker のイメージが作成され、Heroku 上で動作するように配置されます。
-
heroku open
で、デプロイされたアプリへ、ブラウザでアクセスします(GUIでも可)。
設定・デプロイ上の注意事項
とまぁ、コマンドがちょっとちがうものの、HerokuへのDockerデプロイは、それほど困難はありません。ただ、Heroku固有の制約があります。それらについて説明します。
-
PORT
環境変数で Listen する Webアプリケーションであること - Network link は未サポート
- Default working directory = '/'。変更するときは
WORKDIR
を指定する。 -
CMD
が必須。ENTRYPOINT
はオプション。 -
VOLUME
、EXPOSE
、STOPSIGNAL
、SHELL
、HEALTHCHECK
は未サポート
Heroku は Webアプリケーションを動かすためのプラットフォームです。また、環境変数 PORT
で指定されたポートで LISTENしていないと、「こりゃ不適合アプリだな」としてアプリをクラッシュさせて停止します。厳密には、PORT
変数で LISTENさえしていれば、Web応答をするかどうかに関係なく実行はできるようです(2017/12/18現在)
したがって、ポート番号を強制するようなEXPOSE
も利用できませんし、そもそも外部のファイルデバイスを利用するという仕組みのないHerokuでは、VOLUME
も利用できないということになります。
ENTRYPOINT
はオプション指定ですが、何も指定していなければ自動的に /bin/sh -c
が指定されます。
複数のイメージを push するには
ディレクトリごとにDockerfile
を準備して、個別にも、いっぺんにでも、まとめてHerokuアプリへpushできます。例えば、次のようなディレクトリ構成だとします。
web/
+- Dockerfile.web
worker-dyno/
+- Dockerfile.worker
worker-test/
+- Dockerfile.test
heroku container:push
に --recursive
を付与して実行します。
heroku container:push --recursive
この場合、web
worker-dyno
worker-test
にある全ての Dockerfile
のイメージが作成され、一つずつが Dyno
として Heroku アプリ上に作られます。この場合では、3つの Dyno
が作られるということですね。
ディレクトリ名はなんでもいいんですが、Dockerfile
のあとは重要な識別子になります。これが Dyno
のプロセスタイプになります。Heroku は Web Dyno
が必要で、それが Webアプリとして実行される Dyno
になります。その他のプロセスタイプの場合は、Worker Dyno
として定義され、バックエンドで実行させることができるようになります。
今回のケースだと、web
「Web Dyno」 一つと worker
test
という2つの「Worker Dyno」がデプロイされるということになります。このプロセスタイプを、Dockerfile
のあとに「.」をつけて付与する必要があります。ただの「Dockerfile」では認識されませんので、お気をつけください。
また、push
時にデプロイするプロセスタイプを指定できます。例えば、web
と test
だけデプロイしたい、ということであれば。
heroku container:push web test --recursive
と指定することになります。この場合でも --recursive
は必要ですのでお忘れなく。
※ Herokuチームにはさんざんレビューいただいて、ホント感謝です。