heroku.yml を使用して Docker イメージをビルドする
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2024年04月25日(木)
Table of Contents
heroku.yml
ファイルは、次の目的で使用されるマニフェストです。
- Heroku で Docker イメージをビルドする
- アプリのプロビジョニング時に作成するアドオンと環境設定を指定する
- Docker ベースのアプリケーションのデプロイ時に Review Apps を利用する
Heroku container
スタックは、高度なユースケースのみを想定しています。カスタム Docker イメージが特に必要な場合を除き、
Docker image の場合は、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 main
アプリケーションをビルドした後、Heroku は Profiles
の代わりに heroku.yml
で提供される run
コマンドを使用します。
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:22-build AS builder
...
FROM heroku/heroku:22 AS production
...
builder
ステージの出力のみを release
イメージとして使用するように指定する heroku.yml
の例を次に示します。
build:
docker:
release:
dockerfile: Dockerfile
target: builder
web: Dockerfile
Release: Release Phase を構成する
Release Phase では、新しいリリースが本番環境にデプロイされる前にタスクを実行できます。たとえば、CSS/JS/アセットを CDN に送信したり、キャッシュストアを準備したり、データベーススキーマの移行を実行したりします。
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
も含まれている場合は、これは無視され、代わりに 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
--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 main
いつでも、stable アップデートストリームに戻して、プラグインを削除できます。
$ heroku update stable
$ heroku plugins:remove manifest
既知の問題と制限事項
- 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
を渡して無効にします。- 基礎となるコンテナランタイムの既知の問題と制限事項も適用されます。