heroku.yml を使用して Docker イメージをビルドする
最終更新日 2022年11月02日(水)
Table of Contents
heroku.yml
ファイルは、Heroku アプリの定義に使用できるマニフェストです。このファイルでは、以下のことができます。
- Heroku で Docker イメージをビルドする
- アプリのプロビジョニング時に作成するアドオンと環境設定を指定する
- Docker ベースのアプリケーションのデプロイ時に Review Apps を利用する
Heroku container
スタックは、高度なユースケースのみを想定しています。カスタム Docker イメージが特に必要な場合を除き、
Heroku のデフォルト buildpack を利用したビルドシステムを代わりに使用することをお勧めします。これにより、
スタックイメージの自動セキュリティ更新、言語固有の最適化が提供され、Dockerfile
を保守する必要がなくなります。
はじめに
アプリケーションのルートディレクトリに
heroku.yml
ファイルを作成します。次のheroku.yml
の例では、アプリのweb
プロセス用にビルドする Docker イメージを指定しています。build: docker: web: Dockerfile run: web: bundle exec puma -C config/puma.rb
この例では、
heroku.yml
とDockerfile
の両方が同じディレクトリにあります。Dockerfile
がルート以外のディレクトリに置かれている場合は、build.docker.web
値で相対パス (app/Dockerfile
など) を指定します。If you don’t include a
run
section, Heroku uses theCMD
specified in theDockerfile
.ファイルを自分のリポジトリにコミットします。
$ git add heroku.yml $ git commit -m "Add heroku.yml"
アプリのスタックを
container
に設定します。$ heroku stack:set container
アプリを Heroku にプッシュします。
$ git push heroku master
アプリケーションがビルドされ、Procfile
ではなく、heroku.yml
で指定された run
コマンドが Heroku で使用されるようになります。
heroku.yml の概要
heroku.yml
マニフェストには、次の 4 つのトップレベルセクションがあります。
setup
- アプリのプロビジョニング時に作成するアドオンと環境設定を指定します。build
- ビルドするDockerfile
を指定します。release
- 実行するRelease Phase のタスクを指定します。run
- 実行するそれぞれのプロセスタイプとコマンドを指定します。
上記の各セクションの詳細は、この後で説明します。
heroku.yml
マニフェストを使用して Docker イメージをビルドする様子を示した例を次に示します。
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: アプリの環境を定義する
アドオンを構成する
heroku.yml
では、アプリのプロビジョニング時にアドオンが作成されるようにできます。アドオンをプロビジョニングするには、setup.addons
セクションに追加します。
setup:
addons:
- plan: heroku-postgresql
as: DATABASE
任意の as
オプションを使用すると、同じアドオンプロバイダーの名前が異なる複数のインスタンスをアタッチできます。
環境設定を設定する
heroku.yml
では、アプリのプロビジョニング時に環境設定が設定されるようにできます。環境設定を設定するには、setup.config
セクションに追加します。
setup:
config:
S3_BUCKET: my-example-bucket
setup
からアプリを作成する方法を確認してください。
build: ビルドを定義する
heroku.yml
に対する相対パスを使って Dockerfile
を指定します。
build:
docker:
web: Dockerfile
worker: worker/Dockerfile
Docker のビルドコンテキストが Dockerfile が格納されているディレクトリに設定されます。
run
セクションを指定しない場合は、Dockerfile で指定されている CMD
が使用されます。
ビルド時の環境変数を設定する
build
セクションの config
フィールドでは、ビルド環境に使用できる環境変数を設定できます。 このセクションの変数セットでは、ランタイムの環境設定は作成されません。 また、ランタイムの環境設定 (たとえば、heroku config:set
で設定されるものなど) は、ビルド時には使用できません。
build:
config:
RAILS_ENV: development
FOO: bar
ビルド時の環境変数は、それぞれ Dockerfile
内の ARG
行と一致する必要があります。
ARG RAILS_ENV=production
ARG FOO
マルチステージビルドの 1 つのステージを対象にする
マルチステージの Docker ビルドを使用して、1 つの Dockerfile
でアプリケーションのビルドや本番イメージを管理することができます。 たとえば、ビルドとリリース時にのみ使用可能で、最終的な本番イメージには使用できない特定のパッケージまたはデータベース移行スクリプトを使用することができます。
マルチステージの Dockerfile
の例を次に示します。 builder
ステージにはデータベース移行スクリプトが含まれ、production
ステージにはアプリの実行に必要なアプリのコードと依存関係のみがあります。
FROM heroku/heroku:18-build AS builder
...
FROM heroku/heroku:18 AS production
...
builder
ステージの出力のみを release
イメージとして使用するように指定する heroku.yml
の例を次に示します。
build:
docker:
release:
dockerfile: Dockerfile
target: builder
web: Dockerfile
release: Release Phase を構成する
Release Phase では、新しいリリースが本番環境にデプロイされる前にタスクを実行できます (たとえば、CDN への CSS/JS/ アセットの送信、キャッシュストアの準備、データベーススキーマの移行の実行など)。
Release Phase のコマンドを定義するには、heroku.yml
マニフェスト内の release
セクションで command
および使用したい image
を指定します。
build:
docker:
web: Dockerfile
worker: worker/Dockerfile
release:
image: worker
command:
- ./deployment-tasks.sh
ランタイムの環境設定 (データベース接続 URL など) は、Release Phase 中に使用できます。
Release Phase の実行中にログのストリーム出力を表示する場合は、Docker イメージに curl
が含まれている必要があります。Docker イメージに curl が含まれていない場合、Release Phase のログはアプリケーションのログで参照できます。ベースイメージとして Heroku スタックを使用している場合は、curl
が含まれています。
run: 実行するプロセスを定義する
run
セクションでは、アプリケーションの起動時に Heroku によって実行されるプロセスを定義できます。プロジェクトに Procfile
も含まれている場合、Procfile は無視され、代わりに run
が使用されます。
run:
web: bundle exec puma -C config/puma.rb
特定の Docker イメージを複数のプロセスに使用する場合は、image
で指定します。
build:
docker:
web: Dockerfile
run:
web: bundle exec puma -C config/puma.rb
worker:
command:
- python myworker.py
image: web
heroku.yml
マニフェストに run
セクションを含めない場合は、代わりに Dockerfile
CMD
が使用されます。
Docker イメージのランタイム要件の詳細については、「Container Registry と Runtime」のドキュメントを確認してください。
Review Apps と app.json
heroku.yml
マニフェストで Review Apps を使用する場合も、app.json
ファイルは必要です。必ず app.json
ファイル内の stack
値を container
に設定してください。
Docker イメージを使用しているアプリは pr-predestroy
スクリプトを使用できません。これらのスクリプトは、app.json
ファイルに含まれていると無視されます。
‘setup’ からアプリを作成する
setup
からのアプリの作成は、現在、ベータ版です。 フィードバックは、heroku-build-manifest-feedback@salesforce.com までメールでお送りください。
heroku.yml
マニフェスト内で定義されている setup
セクションからアプリを作成するには、beta
アップデートチャネルから heroku-manifest
プラグインをインストールしてください。
$ heroku update beta
$ heroku plugins:install @heroku-cli/plugin-manifest
いつでも、stable アップデートストリームに戻して、プラグインを削除できます。
$ heroku update stable
$ heroku plugins:remove manifest
次に、--manifest
フラグを使用してアプリを作成します。 アプリのスタックは自動的に container
に設定されます。
$ heroku create your-app-name --manifest
Creating ⬢ your-app-name... done, stack is container
Adding heroku-postgresql... done
Setting config vars... done
heroku.yml
を Git にコミットします。
$ git add heroku.yml
$ git commit -m "Added heroku.yml"
コードをプッシュします。
$ git push heroku master
既知の問題と制限事項
- Docker イメージレイヤーのキャッシングはサポートされていません。
- Private Spaces では
heroku.yml
でのrun
セクションの使用は推奨されないため、代わりにコマンドを Dockerfile で指定する必要があります。 - Dockerfile の
FROM
行ではプライベートリポジトリやプライベートレジストリはサポートされません。 - Docker のビルドコンテキストは常に
Dockerfile
が格納されているディレクトリに設定され、個別に構成することはできません。 heroku.yml
のビルドが実行される環境では、ランタイム環境や dyno サイズの選択に応じて、実行時のものとは少し異なる CPU の世代が使用される可能性があるため、特定の CPU 命令セット用にコンパイルされたバイナリ実行可能ファイルが実行時に動作しないことがあります。実行時にIllegal instruction
エラーが発生した場合は、ビルド時コンパイルオプションを調整して CPU 固有の最適化を無効にしてみてください。GCC を使用している場合、これを行うには-march=x86-64 -mtune=generic
をコンパイラに渡します。- 基礎となるコンテナランタイムの既知の問題と制限事項も適用されます。