The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
このページを編集

Heroku へのデプロイ

このガイドでは、Quarkus ベースの Web アプリケーションを web-dyno として Heroku にデプロイする方法を説明します。

このガイドでは以下をカバーしています。

  • Quarkus の HTTP ポートの更新

  • Heroku CLI のインストール

  • アプリケーションの Heroku へのデプロイ

  • アプリケーションのコンテナーイメージとしての Heroku へのデプロイ

    • Docker の使用

    • Podman の使用

  • ネイティブアプリケーションのコンテナーイメージとしての Heroku へのデプロイ

要件

このガイドを完成させるには、以下が必要です:

  • ざっと 1 hour for all modalities

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.9

  • 使用したい場合は、 Quarkus CLI

  • Heroku アカウント。アプリケーションをデプロイするには、少なくとも Eco アカウントが必要です。

  • Heroku CLIのインストール

はじめに

Heroku は開発者がアプリケーションの構築、実行、運用をすべてクラウド上で行うことができるPaaS (Platform as a Service)、PHP、Go などの言語をサポートしています。 さらに、あらかじめ構築されたコンテナーイメージをデプロイするためのコンテナーレジストリーも提供しています。

Herokuは、Quarkusのアプリケーションを実行するためにさまざまな方法で使用できます。

  • Heroku の環境で定義されたコンテナー内で動作するプレーンな Java プログラムとして

  • Quarkus のビルドプロセスで定義されたコンテナー内で実行されるコンテナー化された Java プログラムとして

  • Quarkus のビルドプロセスで定義されたコンテナー内で実行されるコンテナー化されたネイティブプログラムとして

この 3 つのアプローチはいずれも、トラフィックを処理するために Heroku が割り当てるポートを意識する必要があります。 幸運なことに、そのための動的な設定プロパティーがあります。

プロジェクトの共通設定

このガイドでは、Quarkus ツールを使用して作成されたシンプルなアプリケーションを入力として取り扱います。

コマンドラインインタフェース
quarkus create app org.acme:getting-started-with-heroku
cd getting-started-with-heroku

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストールと使用方法の詳細については、 Quarkus CLI ガイドを参照してください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.19.4:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started-with-heroku
cd getting-started-with-heroku

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

Windowsユーザーの場合:

  • cmdを使用する場合、(バックスラッシュ \ を使用せず、すべてを同じ行に書かないでください)。

  • Powershellを使用する場合は、 -D パラメータを二重引用符で囲んでください。例: "-DprojectArtifactId=getting-started-with-heroku"

このコマンドは、getting-started-with-heroku ディレクトリーに新しい REST アプリケーションを作成します。

このアプリケーションを Git リポジトリーにしてみましょう。

  1. アプリケーションディレクトリーに移動します: cd getting-started-with-heroku

  2. 新しい Git リポジトリーを初期化します: git init -b main

  3. すべてのファイルをリポジトリーに追加します: git add .

  4. ファイルをコミットします: git commit -a -m 'Initial copy of getting-started'

Heroku ではリポジトリーの変更を起点に CI を実行し、コードが変更されたときにアプリケーションを再デプロイすることができます。 したがって、すでに有効なリポジトリーがある前提で説明します。

また、Heroku CLI が動作していることを確認してください。

heroku --version
heroku login

Quarkus の HTTP ポートの準備

Heroku はランダムにポートを選択し、最終的に Quarkus アプリケーションを実行するコンテナーに割り当てます。 このポートは、$PORT の環境変数として利用できます。 すべてのデプロイメントシナリオで Quarkus にそれを認識させる最も簡単な方法は、以下の設定を使用することです。

quarkus.http.port=${PORT:8080}

これは、「定義済みの変数の場合は $PORT をリッスンし、それ以外の場合は通常通り 8080 をリッスンする」と読み取れます。 以下を実行して、これを application.properties に追加します。

echo "quarkus.http.port=\${PORT:8080}" >> src/main/resources/application.properties
git commit -am "Configure the HTTP Port."

リポジトリのデプロイとHerokuでのビルド

1 つ目は、Quarkus の Maven ビルドを使用して、実行可能な "fast-jar "と Heroku のビルドインフラに必要なすべてのライブラリーを含む quarkus-app アプリケーション構造を作成し、 その結果をデプロイするもので、もう 1 つはローカルビルドプロセスを使用して最適化されたコンテナーを作成するものです。

最初のバリエーションでは、アプリケーションのルートディレクトリに 2 つの追加ファイルが必要です:

  • Javaのバージョンを設定する為に system.properties

  • Herokuがアプリケーションを開始する方法を設定するために Procfile

QuarkusにはJDK 17が必要なので、まずそれを指定します:

echo "java.runtime.version=17" >> system.properties
git add system.properties
git commit -am "Configure the Java version for Heroku."

今回はWebアプリケーションをデプロイするので、Heroku Procfile でタイプ web を以下のように設定する必要があります。

echo "web: java \$JAVA_OPTS -jar target/quarkus-app/quarkus-run.jar" >> Procfile
git add Procfile
git commit -am "Add a Procfile."

アプリケーションは、リポジトリーの root ディレクトリーから heroku local web 経由ですでに実行可能である必要があります。これを成功させるには、事前に mvn package を実行して実行可能な JAR ファイルを作成しておく必要があります。

続いて、アカウントでアプリケーションを作成し、そのリポジトリーをそこにデプロイしてみましょう。

heroku create

これにより、Heroku アカウントにリモートリポジトリーが作成され、ローカルリポジトリーに heroku リモート URL も追加されます。これは、git remote -v を使用して表示できます。

starksm@Scotts-Mac-Studio getting-started % git remote -v
heroku	https://git.heroku.com/young-shelf-58876.git (fetch)
heroku	https://git.heroku.com/young-shelf-58876.git (push)

これで、アプリケーションを Heroku にプッシュし、ブラウザーで開くことができます。

git push heroku main
heroku open hello

アプリケーションには生成された URL があり、ターミナルにそれが出力されます。heroku open hello は、'/hello' コンテキストを使用して新しいアプリケーションにアクセスするためにデフォルトのブラウザーを開きます。そのページには 'hello' というテキストが出力されます。

curl 経由で REST エンドポイントにアクセスするには、heroku info コマンドからアプリケーション URL を取得します。

heroku info | grep  "Web URL:"
APP_NAME=<https url info>
curl $APP_NAME/hello

もちろん、Heroku CLIを使ってこのレポジトリをGitHubアカウントに接続することもできますが、これはこのガイドでは対象外です。

コンテナーとしてデプロイ

コンテナー全体をプッシュすることの利点は、その内容を完全にコントロールできることであり、GraalVM 上で動作するネイティブ実行可能ファイルを持つコンテナーをデプロイすることも可能です。

まず、Heroku のコンテナーレジストリーにログインします。

heroku container:login

コンテナーイメージをビルドする機能を追加するには、プロジェクトにエクステンションを追加する必要があります。

コマンドラインインタフェース
quarkus extension add container-image-docker
Maven
./mvnw quarkus:add-extension -Dextensions='container-image-docker'
Gradle
./gradlew addExtension --extensions='container-image-docker'

次に、この変更をコミットします。

git add pom.xml
git commit -am "Add container-image-docker extension."

これからビルドするイメージは、Heroku のレジストリーやデプロイメントと連携するために、適切な名前を付ける必要があります。heroku info を通して生成された名前を取得し、それを (ローカル) ビルドに渡します。

APP_NAME=`heroku info | grep  "=== .*" |sed "s/=== //"`
./mvnw clean package\
  -Dquarkus.container-image.build=true\
  -Dquarkus.container-image.group=registry.heroku.com/$APP_NAME\
  -Dquarkus.container-image.name=web\
  -Dquarkus.container-image.tag=latest

イメージをプッシュしてリリースする

これで、イメージをプッシュしてリリースできるようになりました。

イメージの全レイヤーを転送する必要があるため、最初のプッシュはかなり大きくなります。 それ以降のプッシュは小さくなります。

Dockerによるプッシュ

Dockerがインストールされていれば、これらの手順は簡単です:

docker push registry.heroku.com/$APP_NAME/web
heroku stack:set container
heroku container:release web --app $APP_NAME

Podmanを通じたプッシュ

Podman を Docker の代替品として使用したい場合、Heroku CLI は Docker に依存しており、OCI 形式をサポートしていないため、いくつかの問題が発生します。ただし、これらの問題には解決策があります。

Cannot find docker, please ensure docker is installed.

問題は、明らかに heroku-cli が docker を見つけられないことです。podman cli は docker と互換性があるため、これは簡単に解決できます。podman から docker へのシンボリックリンクを作成するだけです。

sudo ln -s $(which podman) /usr/local/bin/docker
Error writing manifest: Error uploading manifest latest to registry.heroku.com/$APP_NAME/web: unsupported

通常の podman push (OCI 形式) を実行する代わりに、回避策を使用して、Podman と Heroku CLI を介してアプリケーションを目的の形式 (v2s2 - Docker Image Manifest Version 2、Schema 2) でプッシュおよびリリースする必要があります。また、https://github.com/containers/skopeo[skopeo] も必要です。

CONTAINER_DIR="target/container-dir"
mkdir $CONTAINER_DIR
podman push --format=v2s2 "registry.heroku.com/$APP_NAME/web" dir:$CONTAINER_DIR
skopeo --debug copy dir:$CONTAINER_DIR "docker://registry.heroku.com/$APP_NAME/web:latest"
heroku container:release web --app "$APP_NAME"
rm -rf $CONTAINER_DIR

ログの確認

アプリケーションが実際にコンテナーから実行されているかどうか、ログを確認することができますし、確認すべきです。

heroku logs --app $APP_NAME --tail

コンテナー内にネイティブアプリケーションとしてデプロイ

アプリケーションをコンテナーとしてデプロイする際の最大のメリットは、ネイティブにコンパイルされたアプリケーションを使ってコンテナーをデプロイすることです。その理由は、Heroku は着信トラフィックがないときにアプリケーションを停止またはスリープさせるからです。ネイティブアプリケーションは、スリープ状態からより早く目覚めます。

プロセスはほとんど同じです。 ここでは、ローカルコンテナー内でネイティブイメージをコンパイルすることを選択し、ローカルに GraalVM をインストールする必要がないようにしています。

APP_NAME=`heroku info | grep  "=== .*" |sed "s/=== //"`
./mvnw clean package \
  -Dquarkus.container-image.build=true \
  -Dquarkus.container-image.group=registry.heroku.com/$APP_NAME \
  -Dquarkus.container-image.name=web \
  -Dquarkus.container-image.tag=latest \
  -Dnative \
  -Dquarkus.native.container-build=true

その後、Docker または Podman (上記参照) を使用して再度プッシュおよびリリースし、ログを確認します。

関連コンテンツ