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 は開発者がアプリケーションの構築、実行、運用をすべてクラウド上で行うことができるPaaS (Platform as a Service)、PHP、Go などの言語をサポートしています。 さらに、あらかじめ構築されたコンテナーイメージをデプロイするためのコンテナーレジストリーも提供しています。
Herokuは、Quarkusのアプリケーションを実行するためにさまざまな方法で使用できます。
-
Heroku の環境で定義されたコンテナー内で動作するプレーンな Java プログラムとして
-
Quarkus のビルドプロセスで定義されたコンテナー内で実行されるコンテナー化された Java プログラムとして
-
Quarkus のビルドプロセスで定義されたコンテナー内で実行されるコンテナー化されたネイティブプログラムとして
この 3 つのアプローチはいずれも、トラフィックを処理するために Heroku が割り当てるポートを意識する必要があります。 幸運なことに、そのための動的な設定プロパティーがあります。
プロジェクトの共通設定
このガイドでは、Quarkus ツールを使用して作成されたシンプルなアプリケーションを入力として取り扱います。
Windowsユーザーの場合:
-
cmdを使用する場合、(バックスラッシュ
\
を使用せず、すべてを同じ行に書かないでください)。 -
Powershellを使用する場合は、
-D
パラメータを二重引用符で囲んでください。例:"-DprojectArtifactId=getting-started-with-heroku"
このコマンドは、getting-started-with-heroku
ディレクトリーに新しい REST アプリケーションを作成します。
このアプリケーションを Git リポジトリーにしてみましょう。
-
アプリケーションディレクトリーに移動します:
cd getting-started-with-heroku
-
新しい Git リポジトリーを初期化します:
git init -b main
-
すべてのファイルをリポジトリーに追加します:
git add .
-
ファイルをコミットします:
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
./mvnw quarkus:add-extension -Dextensions='container-image-docker'
./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 へのシンボリックリンクを作成するだけです。
|
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] も必要です。
|
コンテナー内にネイティブアプリケーションとしてデプロイ
アプリケーションをコンテナーとしてデプロイする際の最大のメリットは、ネイティブにコンパイルされたアプリケーションを使ってコンテナーをデプロイすることです。その理由は、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 (上記参照) を使用して再度プッシュおよびリリースし、ログを確認します。