Docker Advent Calendar 2018 23日目、本日はかしゆかの誕生日、おめでとうございます。みなさまからも祝福をいただけることをお祈りしながら、本年のネタを紹介します。
昨年のHerou Advent Calendar「Heroku で Docker を使う場合の諸注意」からの Docker
on Heroku 情報について、Heroku の Advent Calendar ではなく、Docker
まで出張ってきての情報発信です。えげつなくてごめんなさい。
Building Docker Images with heroku.yml
2018/11/13に「Building Docker images with heroku.yml is now generally available」として、新しい機能が公開されました。
昨年の執筆時点では、手元で準備したDockerイメージをコンテナリポジトリへ登録することによって、Heroku上で公開できるような仕組みとなっていました。「DockerイメージをHerokuに配置できる」という状況ですね。たしかにHerokuの上で動かすことはできていました。
今回の更新で何ができるようになったかと申し上げますと、「Heroku上でDockerイメージをビルドできるようになった」です。これにあわせて、heroku.yml
というマニフェストファイルの記述が必要になったのですが、これがまたお便利を助長するような素晴らしいものなので、ご連絡に上がった次第です。
これまでのDockerfile
を活かしたまま、Herokuのアドオンや設定情報一緒に定義して、Dockerを実行できるようになりました。感覚的にはdocker-compose
で一つのサービスに必要なDockerイメージをまるごと作って、全部でプロイしちゃおうに近しいです。
手元でビルドが不用意なったので...
- 手元に docker がなくてもアプリが作れる
- github と連携して Review Apps が作れる
ソースコードのまま管理できるようになったので、ようやく開発ライフサイクルに載せられるようになったわけです。これってすごい進化じゃないですか。
heroku.yml の実態
サンプルをそのまま紹介します。
setup:
addons:
- plan: heroku-postgresql
as: DATABASE
config:
S3_BUCKET: my-example-bucket
build:
docker:
web: Dockerfile
worker: worker/Dockerfile
config:
RAILS_ENV: development
FOO: bar
release:
command:
- ./deployment-tasks.sh
image: worker
run:
web: bundle exec puma -C config/puma.rb
worker: python myworker.py
asset-syncer:
command:
- python asset-syncer.py
image: worker
setup:
setup:
では、Heroku アプリケーションの環境定義を記述できます。
例えば使いたいアドオンだったり、環境変数の定義です。というかそれらが定義できます。このサンプルでは、Heroku Postgres
アドオンをプロビジョンし、S3_BUCKET
環境変数を定義しています。
build:
Docker
イメージとプロセスタイプのヒモ付や、ビルドの際に必要な環境変数の定義ができます。
ここでは、web
プロセスタイプのDockerイメージは、ソースコードツリーのルートにあるDockerfile
を使ってイメージを生成しろ、worker
プロセスタイプのDockerイメージは、worker/Dockerfile
を使ってイメージを準備しろという指示をしています。
config
内で環境変数が定義されています。RAILS_ENV
とFOO
ですね。ビルドのときに使われる環境変数です。
もう一つ release
というものがあります。これは、本家機能の Release Phase
と同じもので、デプロイしたときに「一度だけ」実行されるタスクを指定します。例えば、データベースのマイグレーションであったり、CDNのキャッシュ更新など、ソースコードや構成が変更されることによって、実行しておくべきことをデプロイ時に実行できるというお得機能です。ええやんけ。
run:
run:
では、Procfileで指定するように、プロセスタイプごとの起動コマンドを設定します。
ここでは、web
とworker
のプロセスタイプを前もって準備していたので、各々について定義されていますね。それとは別に、asset-syncer
が増えています。image:
で定義されている Dockerイメージ内で起動できる別のプロセスタイプも個々で指定できるようになっています。
プロセスタイプごとにDockerのイメージを作るということは現実的ではありませんね。一つのイメージの中でも、複数のプロセスタイプで起動できるよう、定義もできるようになっています。
デプロイする前に
あとは、通常通りデプロイすればよいのですが、Heroku側には「これはDockerですよ」という指示を事前にしておく必要があります。基本的に各言語、自動的に検出してランタイム環境を自動的に生成してくれるHeroku様ですが、Dockerに限っては、まだ手動設定が必要です。
とはいえ、次の一つだけです。Herokuアプリケーションを準備したら
heroku stack:set container
としてあげるだけです。カンタンですね。