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

  • A Heroku Account. You need at least an Eco account to deploy an application.

  • Heroku CLIのインストール

はじめに

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

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

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

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

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

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

プロジェクトの共通設定

This guide will take as input a simple application created with the Quarkus tooling:

コマンドラインインタフェース
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.18.3: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"

This command will create a new REST application in the getting-started-with-heroku directory.

Let’s make this application a Git repository:

  1. Change to the application directory: cd getting-started-with-heroku.

  2. Initialize a new Git repository: git init -b main.

  3. Add all files to the repository: git add ..

  4. Commit the files: 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."

Your application should already be runnable via heroku local web from the repository root directory. You need to have run mvn package before to create the runnable jar for this to succeed.

Now let’s create an application in your account and deploy that repository to it:

heroku create

This will create a remote repository in your Heroku account, and it should have also added a heroku remote url to your local repository which you can view using 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)

Now you can push your application to Heroku and open it in your browser.

git push heroku main
heroku open hello

The application will have a generated URL and the terminal should output that. heroku open hello opens your default browser to access your new application using the '/hello' context. That page should output the text 'hello'.

To access the REST endpoint via curl, get the app URL from the heroku info command:

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

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

コンテナとしてデプロイ

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

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

heroku container:login

We need to add an extension to our project to add the capability to build container images:

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

Then, let’s commit this change:

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プッシュ(OCIフォーマット)の代わりに、PodmanとHeroku CLIを通してアプリを希望のフォーマット(v2s2 - Docker Image Manifest Version 2, Schema 2)でプッシュ・リリースするには、回避策を使用する必要があります。また、 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(上記参照)を使って再度プッシュ・リリースし、ログを確認してください。

関連コンテンツ