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は開発者がアプリケーションの構築、実行、運用をすべてクラウド上で行うことができる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:
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:
-
Change to the application directory:
cd getting-started-with-heroku
. -
Initialize a new Git repository:
git init -b main
. -
Add all files to the repository:
git add .
. -
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
./mvnw quarkus:add-extension -Dextensions='container-image-docker'
./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へのシンボリックリンクを作成するだけです:
|
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 も必要です。
|
コンテナ内にネイティブ・アプリケーションとしてデプロイ
アプリをコンテナとしてデプロイする際の最大のメリットは、ネイティブにコンパイルされたアプリを使ってコンテナをデプロイすることです。なぜか?なぜなら、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(上記参照)を使って再度プッシュ・リリースし、ログを確認してください。