ネイティブ実行ファイルのビルド
このガイドの内容:
-
アプリケーションをネイティブ実行ファイルにコンパイルする
-
ネイティブ実行ファイルをコンテナーにパッケージングする
-
ネイティブ実行ファイルのデバッグ
このガイドでは、 Getting Started ガイド で作成したアプリケーションを前提としています。
前提条件
このガイドを完成させるには、以下が必要です:
-
約15分
-
IDE
-
JDK 17+がインストールされ、
JAVA_HOMEが適切に設定されていること -
Apache Maven 3.9.15
-
動作するコンテナランタイム(Docker, Podman)
-
使用したい場合は、 Quarkus CLI
-
MandrelまたはGraalVMがインストールされ、 適切に設定されていること
-
Getting Started ガイド で開発されたアプリケーションのコード。
|
C によるネイティブコンパイルのサポート
「動作する C 開発環境がある」とはどういう意味ですか?
|
背景
ネイティブ実行ファイルのビルドには、GraalVM のディストリビューションを使用する必要があります。ディストリビューションには、Oracle GraalVM Community Edition (CE)、Oracle GraalVM Enterprise Edition (EE)、Mandrel の 3 つがあります。Oracle と Mandrel のディストリビューションの違いは以下の通りです。
-
Mandrel は Oracle GraalVM CE のダウンストリームディストリビューションです。Mandrel の主な目的は、Quarkus をサポートするために特別に設計されたネイティブ実行ファイルをビルドする方法を提供することです。
-
Mandrel のリリースは、アップストリームの Oracle GraalVM CE コードベースから派生したコードベースからビルドされており、変更はわずかですが、Quarkus ネイティブアプリには不要ないくつかの重要な機能が除外されています。これらは、Oracle GraalVM CE と同じネイティブ実行ファイルビルド機能をサポートしており、機能に大きな違いはありません。特に、ポリグロットプログラミングのサポートは含まれていません。これらの除外の理由は、大多数の Quarkus ユーザーに対してより良いレベルのサポートを提供するためです。また、これらの除外により、Mandrel は Oracle GraalVM CE/EE と比較して配布サイズを大幅に削減できています。
-
Mandrel は、標準の OpenJDK プロジェクトを使用して、Oracle GraalVM CE とは少し異なる方法でビルドされています。これは、Oracle が自社の GraalVM ダウンロード版をビルドするために使用している OpenJDK のバージョンに加えた、いくつかの小さな拡張機能の恩恵を受けられないことを意味します。これらの拡張機能は、アップストリームの OpenJDK がそれらを管理しておらず、保証もできないため省略されています。これは、適合性やセキュリティーの面で特に重要です。
-
Mandrel は、Linux コンテナー環境をターゲットとするネイティブ実行ファイルのビルドに推奨されます。つまり、Mandrel ユーザーは、ネイティブ実行ファイルのビルドにコンテナーを使用することが推奨されます。amd64/x86 上の macOS 用にネイティブ実行ファイルをビルドする場合は、Mandrel が現在このプラットフォームをターゲットにしていないため、代わりに Oracle GraalVM の使用を検討してください。ベアメタル Linux、macOS (M プロセッサー)、または Windows 上で直接ネイティブ実行ファイルをビルドすることも可能です。詳細は Mandrel README および Mandrel リリース で確認できます。
GraalVM の設定
|
この手順は、Linux 以外のオペレーティングシステムをターゲットとするネイティブ実行ファイルを生成する場合にのみ必要です。Linux をターゲットとするネイティブ実行ファイルを生成する場合は、このセクションをスキップして、代わりに ビルダーイメージを使用 することもできます。 |
|
GraalVM をインストールできない場合は、マルチステージ Docker ビルドを使用して、GraalVM が組み込まれた Docker コンテナー内で Maven を実行できます。その方法については、 このガイドの最後 で説明しています。 |
GraalVM for JDK 21 が必要です。
-
まだインストールしていない場合は、GraalVM をインストールしてください。いくつかのオプションがあります。
-
https://github.com/graalvm/mandrel/releases または https://github.com/graalvm/graalvm-ce-builds/releases から適切なアーカイブをダウンロードし、他の JDK と同じように解凍します。
-
sdkman、 homebrew、 scoop などのプラットフォーム固有のインストーラーツールを使用します。GraalVM の community edition を推奨します。例えば、
sdk install java 21-graalceでインストールします。
-
-
ランタイム環境を設定します。
GRAALVM_HOME環境変数を GraalVM のインストールディレクトリーに設定します。例:export GRAALVM_HOME=$HOME/Development/mandrel/macOS (amd64/x86 ベースの Mac はサポートされていません) では、変数を
Homeサブディレクトリーに指定します。export GRAALVM_HOME=$HOME/Development/graalvm/Contents/Home/Windows では、コントロールパネルから環境変数を設定する必要があります。
scoop 経由でインストールすると、これが自動的に行われます。
-
(任意)
JAVA_HOME環境変数を GraalVM のインストールディレクトリーに設定します。export JAVA_HOME=${GRAALVM_HOME} -
(任意) GraalVM の
binディレクトリーをパスに追加します。export PATH=${GRAALVM_HOME}/bin:$PATH
|
macOS で GraalVM を使用する際の問題
この GraalVM の issue で報告されているように、GraalVM のバイナリーは macOS 用に (まだ) 公証されていません。そのため、
回避策として、以下のコマンドを使用して GraalVM インストールディレクトリーの
|
解決策
次のセクションの手順に従って、アプリケーションをステップバイステップでパッケージングすることをお勧めします。ただし、完成したサンプルを直接確認することもできます。
Git リポジトリーをクローンするか (git clone https://github.com/quarkusio/quarkus-quickstarts.git)、 アーカイブ をダウンロードします。
解決策は getting-started ディレクトリーにあります。
ネイティブ実行ファイルの生成
アプリケーション用のネイティブ実行ファイルには、アプリケーションコード、必要なライブラリー、Java API、および削減されたバージョンの VM が含まれます。VM ベースを小さくすることで、アプリケーションの起動時間が向上し、ディスク占有フットプリントが最小限に抑えられます。

前のチュートリアルからアプリケーションを生成した場合は、pom.xml に以下の Maven プロファイルセクションがあります。
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.native.enabled>true</quarkus.native.enabled>
</properties>
</profile>
</profiles>
|
慣例として、 ネイティブイメージのビルドプロセスの設定方法に関する詳細は、以下の ネイティブイメージバンドルの作成 セクションを参照してください。 |
プロファイルを使用するのは、すぐにお分かりいただけると思いますが、ネイティブ実行ファイルのパッケージングには 数 分かかるためです。コマンドラインのプロパティーとして -Dquarkus.native.enabled=true を渡すだけでも可能ですが、プロファイルを使用することでネイティブイメージテストも実行できるようになるため、プロファイルを使用する方が適しています。
以下を使用してネイティブ実行ファイルを作成します。
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true
|
Windows でのパッケージングに関する問題
パッケージングの前に、Microsoft Native Tools for Visual Studio を初期化する必要があります。これは、Visual Studio Build Tools と共にインストールされた もう 1 つの解決策は、これを自動的に行うスクリプトを作成することです。
|
通常のファイルに加えて、ビルドによって target/getting-started-1.0.0-SNAPSHOT-runner も生成されます。これは ./target/getting-started-1.0.0-SNAPSHOT-runner で実行できます。
|
Java プレビュー機能
プレビュー機能に依存する Java コードには特別な注意が必要です。ネイティブ実行ファイルを生成するには、基盤となる native-image の呼び出しに |
完全な静的ネイティブ実行ファイルのビルド
| 完全な静的ネイティブ実行ファイルのサポートは試験運用版です。 |
Linux では、システムの共有ライブラリーに依存しないネイティブ実行ファイルをパッケージングすることが可能です。満たすべき いくつかのシステム要件 があり、native-image 呼び出しと共に追加のビルド引数を使用する必要があります。最低限必要なのは -Dquarkus.native.additional-build-args="--static","--libc=musl" です。
完全な静的バイナリーのコンパイルは、glibc の代わりに musl を静的にリンクすることで行われます。厳密なテストなしに実稼働環境で使用しないでください。
ネイティブ実行ファイルのテスト
ネイティブ実行ファイルの生成はいくつかの問題を引き起こす可能性があるため、ネイティブファイルで実行されているアプリケーションに対してテストを実行することもお勧めします。その理由は Testing ガイド で説明されています。
ネイティブ実行ファイルに対して実行される GreetingResourceIT を確認するには、./mvnw verify -Dnative を使用します。
$ ./mvnw verify -Dnative
...
Finished generating 'getting-started-1.0.0-SNAPSHOT-runner' in 22.0s.
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] docker run --env LANG=C --rm --user 1000:1000 -v /home/zakkak/code/quarkus-quickstarts/getting-started/target/getting-started-1.0.0-SNAPSHOT-native-image-source-jar:/project:z --entrypoint /bin/bash quay.io/quarkus/ubi9-quarkus-mandrel-builder-image:jdk-21 -c objcopy --strip-debug getting-started-1.0.0-SNAPSHOT-runner
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 70686ms
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M7:integration-test (default) @ getting-started ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.acme.getting.started.GreetingResourceIT
Executing "/home/zakkak/code/quarkus-quickstarts/getting-started/target/getting-started-1.0.0-SNAPSHOT-runner -Dquarkus.http.port=8081 -Dquarkus.http.ssl-port=8444 -Dquarkus.log.file.path=/home/zakkak/code/quarkus-quickstarts/getting-started/target/quarkus.log -Dquarkus.log.file.enable=true -Dquarkus.log.category."io.quarkus".level=INFO"
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2023-05-05 10:55:52,068 INFO [io.quarkus] (main) getting-started 1.0.0-SNAPSHOT native (powered by Quarkus 3.0.2.Final) started in 0.009s. Listening on: http://0.0.0.0:8081
2023-05-05 10:55:52,069 INFO [io.quarkus] (main) Profile prod activated.
2023-05-05 10:55:52,069 INFO [io.quarkus] (main) Installed features: [cdi, rest, smallrye-context-propagation, vertx]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.99 s - in org.acme.getting.started.GreetingResourceIT
...
|
デフォルトでは、Quarkus はネイティブテストを自動的に失敗させる前に、ネイティブイメージが起動するのを 60 秒間待ちます。この時間は |
|
この手順は以前は |
プロファイル
デフォルトでは、統合テストは prod プロファイルを使用してネイティブ実行ファイルを ビルド および 実行 の両方を行います。
テスト中に実行ファイルが 動作 する際のプロファイルは、quarkus.test.integration-test-profile プロパティーを使用してオーバーライドできます。application.properties に追加するか、コマンドラインに付加してください: ./mvnw verify -Dnative -Dquarkus.test.integration-test-profile=test。テスト実行時には、%test. 接頭辞の付いたプロパティーが使用されます。
実行ファイルの ビルド時 および 動作時 のプロファイルをオーバーライドするには、quarkus.profile=test プロパティーを使用します (例: ./mvnw clean verify -Dnative -Dquarkus.profile=test)。これは、テスト データをデータベースにインポートするなど、テスト固有のリソースを処理する必要がある場合に便利です。
quarkus.native.resources.includes=version.txt
%test.quarkus.native.resources.includes=version.txt,import-dev.sql
%test.quarkus.hibernate-orm.schema-management.strategy=drop-and-create
%test.quarkus.hibernate-orm.sql-load-script=import-dev.sql
application.properties に前述の例があれば、JVM モードのテスト実行中とネイティブモードのテスト実行中の両方で、Hibernate ORM 管理のデータベースにテストデータが投入されます。本番用の実行ファイルには version.txt リソースのみが含まれ、余計なテストデータは含まれません。
|
あるいは、
|
Java プレビュー機能
|
Java プレビュー機能
プレビュー機能に依存する Java コードには特別な注意が必要です。ネイティブ実行ファイルをテストするには、Surefire プラグインに |
ネイティブ実行ファイルとしての実行時におけるテストの除外
この方法でテストを実行する場合、実際にネイティブで実行されるのはアプリケーションのエンドポイントのみであり、これらは HTTP コール経由でしかテストできません。テストコード自体はネイティブで実行されないため、HTTP エンドポイントを呼び出さないコードをテストしている場合は、それらをネイティブテストの一部として実行するのはおそらく良い考えではありません。
上記のように JVM 実行とネイティブ実行の間でテストクラスを共有する場合、ネイティブイメージに対するテスト時に特定のテストをスキップするために、それらに @DisabledOnIntegrationTest アノテーションを付けることができます。
|
|
既存のネイティブ実行ファイルのテスト
すでにビルドされたネイティブ実行ファイルに対してテストを再実行することも可能です。これを行うには、./mvnw test-compile failsafe:integration-test -Dnative を実行します。これにより、既存のネイティブイメージが検出され、failsafe を使用してそれに対してテストが実行されます。
何らかの理由でプロセスがネイティブイメージを見つけられない場合、または target ディレクトリーに存在しなくなったネイティブイメージをテストしたい場合は、-Dnative.image.path= システムプロパティーで実行ファイルを指定できます。
GraalVM をインストールせずに Linux 実行ファイルを作成する方法
| 次に進む前に、動作するコンテナーランタイム (Docker、podman) 環境があることを確認してください。Windows で Docker を使用している場合は、Docker Desktop のファイル共有設定でプロジェクトのドライブを共有し、Docker Desktop を再起動する必要があります。 |
Quarkus アプリケーション用に Linux ネイティブ実行ファイルを作成するだけでよい場合 (例えばコンテナー環境で実行するため) はよくありますが、そのために適切な GraalVM バージョンをインストールする手間を避けたいこともあります (例えば、CI 環境ではインストールするソフトウェアを最小限に抑えるのが一般的です)。
この目的のために、Quarkus は Docker や podman などのコンテナーランタイムを活用して Linux ネイティブ実行ファイルを作成する非常に便利な方法を提供しています。これを行う最も簡単な方法は、以下を実行することです。
quarkus build --native --no-tests -Dquarkus.native.container-build=true
# The --no-tests flag is required only on Windows and macOS.
./mvnw install -Dnative -DskipTests -Dquarkus.native.container-build=true
./gradlew build -Dquarkus.native.enabled=true -Dquarkus.native.container-build=true
|
デフォルトでは、Quarkus はコンテナーランタイムを自動的に検出します。明示的にコンテナーランタイムを選択したい場合は、以下のように指定できます。 Docker の場合: CLI
Maven
Gradle
podman の場合: CLI
Maven
Gradle
これらは通常の Quarkus 設定プロパティーであるため、常にコンテナーでビルドしたい場合は、毎回指定しなくて済むように |
コンテナーランタイムを使用してそのようにビルドされた実行ファイルは 64 ビット Linux 実行ファイルになるため、お使いのオペレーティングシステムによっては実行できなくなる可能性があります。
|
Quarkus 3.19 以降、ネイティブ実行ファイルのビルドに使用される builder イメージは UBI 9 に基づいています。つまり、コンテナービルドによって生成されるネイティブ実行ファイルも UBI 9 に基づくことになります。したがって、コンテナーをビルドする予定がある場合は、
UBI 8 の利用可能なタグは こちら で、UBI 9 のタグは こちら (UBI 9) で確認できます。 |
|
コンテナービルドを使用してネイティブ実行ファイルを作成しようとした際、JAR のビルドには成功しているにもかかわらず、アプリケーション JAR に対して以下の無効なパスエラーが表示される場合、コンテナーランタイムにリモートデーモンを使用している可能性が非常に高いです。 Error: Invalid Path entry getting-started-1.0.0-SNAPSHOT-runner.jar Caused by: java.nio.file.NoSuchFileException: /project/getting-started-1.0.0-SNAPSHOT-runner.jar この場合は、 この理由は、 |
|
Mandrel の代わりに GraalVM を使用してビルドするには、カスタムのビルダーイメージパラメーターを追加で渡す必要があります。 CLI
Maven
Gradle
上記のコマンドはフローティングタグを指していることに注意してください。ビルダーイメージを最新かつ安全に保つために、フローティングタグを使用することを強くお勧めします。どうしても必要な場合は、特定のタグをハードコードすることもできますが (利用可能なタグについては こちら (UBI 8) および こちら (UBI 9) を参照)、その方法ではセキュリティーアップデートが提供されず、サポート対象外となることに注意してください。 |
コンテナーの作成
container-image エクステンションの使用
Quarkus アプリケーションからコンテナーイメージを作成する最も簡単な方法は、container-image エクステンションのいずれかを利用することです。
これらのエクステンションのいずれかが存在する場合、ネイティブ実行ファイル用のコンテナーイメージの作成は、実質的に単一のコマンドを実行するだけになります。
./mvnw package -Dnative -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true
-
quarkus.native.container-build=trueを指定すると、GraalVM をインストールせずに Linux 実行ファイルを作成できます (これは、ローカルに GraalVM がインストールされていない場合、またはローカルの OS が Linux でない場合にのみ必要です)。
|
リモート Docker デーモンを実行している場合は、 詳細は GraalVM をインストールせずに Linux 実行ファイルを作成する方法 を参照してください。 |
-
quarkus.container-image.build=trueは、最終的なアプリケーションアーティファクト (この場合はネイティブ実行ファイル) を使用してコンテナーイメージを作成するように Quarkus に指示します。
詳細は Container Image ガイド を参照してください。
micro ベースイメージの手動使用
Quarkus Maven プラグインによって生成された JAR を使用してコンテナー内でアプリケーションを実行できます。しかし、このセクションでは、生成されたネイティブ実行ファイルを使用したコンテナーイメージの作成に焦点を当てます。

ローカルの GraalVM インストールを使用する場合、ネイティブ実行ファイルはローカルのオペレーティングシステム (Linux、macOS、Windows など) をターゲットにします。しかし、コンテナーは使用している OS で生成されたものと同じ 実行可能 形式を使用しない場合があるため、( このセクション で説明されているように) コンテナーランタイムを活用して実行可能ファイルを生成するように Maven ビルドに指示します。
生成された実行ファイルは 64 ビット Linux 実行ファイルになるため、OS によっては実行できなくなる可能性があります。しかし、コンテナーにコピーするため問題ありません。プロジェクト生成時に、以下の内容の Dockerfile.native-micro が src/main/docker ディレクトリーに提供されています。
FROM quay.io/quarkus/ubi9-quarkus-micro-image:2.0
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root --chmod=755 target/*-runner /work/application
EXPOSE 8080
USER 1001
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
Quarkus Micro イメージとは?
Quarkus Micro イメージは、ネイティブアプリケーションを実行するための適切な依存関係セットを提供する小さなコンテナーイメージです。これは UBI Micro に基づいています。このベースイメージは、コンテナー内で完璧に動作するように調整されています。 UBI イメージの詳細については以下を参照してください。 UBI イメージは制限なく使用できます。 このページ では、アプリケーションに特定の要件がある場合に |
生成されたネイティブ実行ファイルを削除していない場合は、以下のコマンドで docker イメージをビルドできます。
docker build -f src/main/docker/Dockerfile.native-micro -t quarkus-quickstart/getting-started .
最後に、以下で実行します。
docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-started
minimal ベースイメージの手動使用
プロジェクト生成時に、以下の内容の Dockerfile.native も src/main/docker ディレクトリーに提供されています。
FROM registry.access.redhat.com/ubi9/ubi-minimal:9.6
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root --chmod=0755 target/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
UBI minimal イメージは、前述の micro イメージよりもサイズが大きくなります。これには microdnf パッケージマネージャーなどのより多くのユーティリティーが含まれています。
マルチステージ Docker ビルドの使用
前のセクションでは Maven または Gradle を使用してネイティブ実行ファイルをビルドする方法を示しましたが、それにはまずネイティブ実行ファイルを作成しておく必要があります。さらに、このネイティブ実行ファイルは Linux 64 ビットの実行ファイルである必要があります。
ビルドツールを含む最終的なコンテナーを作成することなく、コンテナー内で直接ネイティブ実行ファイルをビルドしたい場合があります。そのアプローチはマルチステージ Docker ビルドで可能です。
-
第 1 ステージでは Maven または Gradle を使用してネイティブ実行ファイルをビルドします
-
第 2 ステージは、生成されたネイティブ実行ファイルをコピーする最小限のイメージです
|
以下に示す Dockerfile からコンテナーイメージをビルドする前に、デフォルトの |
このようなマルチステージビルドは、以下のように実現できます。
Maven でビルドするための Dockerfile サンプル:
## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/ubi9-quarkus-mandrel-builder-image:jdk-21 AS build
COPY --chown=quarkus:quarkus --chmod=0755 mvnw /code/mvnw
COPY --chown=quarkus:quarkus .mvn /code/.mvn
COPY --chown=quarkus:quarkus pom.xml /code/
USER quarkus
WORKDIR /code
RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.8.1:go-offline
COPY src /code/src
RUN ./mvnw package -Dnative
## Stage 2 : create the docker final image
FROM quay.io/quarkus/ubi9-quarkus-micro-image:2.0
WORKDIR /work/
COPY --from=build /code/target/*-runner /work/application
# set up permissions for user `1001`
RUN chmod 775 /work /work/application \
&& chown -R 1001 /work \
&& chmod -R "g+rwX" /work \
&& chown -R 1001:root /work
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
このマルチステージ Docker ビルドは、ホストマシンから Maven wrapper をコピーします。Maven wrapper (または Gradle wrapper) は、特定のバージョンの Maven/Gradle を提供する便利な方法です。これにより、Maven や Gradle を含むベースイメージを作成する必要がなくなります。プロジェクトに Maven Wrapper をプロビジョニングするには、mvn wrapper:wrapper を使用します。
|
このファイルは Getting Started クイックスタートには含まれていないため、src/main/docker/Dockerfile.multistage に保存してください。
Gradle でビルドするための Dockerfile サンプル:
## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/ubi9-quarkus-mandrel-builder-image:jdk-21 AS build
USER root
RUN microdnf install findutils -y
COPY --chown=quarkus:quarkus gradlew /code/gradlew
COPY --chown=quarkus:quarkus gradle /code/gradle
COPY --chown=quarkus:quarkus build.gradle /code/
COPY --chown=quarkus:quarkus settings.gradle /code/
COPY --chown=quarkus:quarkus gradle.properties /code/
USER quarkus
WORKDIR /code
COPY src /code/src
RUN ./gradlew build -Dquarkus.native.enabled=true
## Stage 2 : create the docker final image
FROM quay.io/quarkus/ubi9-quarkus-micro-image:2.0
WORKDIR /work/
COPY --from=build /code/build/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
プロジェクトで Gradle を使用している場合は、この Dockerfile サンプルを使用できます。src/main/docker/Dockerfile.multistage に保存してください。
docker build -f src/main/docker/Dockerfile.multistage -t quarkus-quickstart/getting-started .
最後に、以下で実行します。
docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-started
|
ネイティブ実行ファイルで SSL サポートが必要な場合は、必要なライブラリーを Docker イメージに簡単に含めることができます。 詳細については、 Using SSL With Native Executables ガイド を参照してください。 |
|
Mandrel の代わりに GraalVM CE を使用するには、 |
Distroless ベースイメージの使用
| Distroless イメージのサポートは試験運用版です。 |
小さなコンテナーイメージを探している場合、 distroless アプローチによってベースレイヤーのサイズを削減できます。distroless の背後にある考え方は、すべての要件、場合によってはアプリケーション自体も含む、単一の最小限のベースイメージを使用することです。
Quarkus は Dockerfile で使用できる distroless ベースイメージを提供しています。アプリケーションをコピーするだけで完了です。
FROM quay.io/quarkus/quarkus-distroless-image:2.0
COPY target/*-runner /application
EXPOSE 8080
USER nonroot
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
Quarkus は quay.io/quarkus/quarkus-distroless-image:2.0 イメージを提供しています。これにはネイティブ実行ファイルを動かすために必要なパッケージが含まれており、サイズはわずか 9MB です。このイメージの上にアプリケーションを追加するだけで、非常に小さなコンテナーイメージが得られます。
Distroless イメージを厳密なテストなしに実稼働環境で使用しないでください。
scratch からのコンテナーイメージ構築
| scratch イメージのサポートは試験運用版です。 |
完全に静的にリンクされたバイナリーをビルドすると、生成されたネイティブ実行ファイルのみを含む scratch イメージ の使用が可能になります。
scratch からイメージをビルドするためのマルチステージ Dockerfile サンプル:
## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/ubi9-quarkus-graalvmce-builder-image:jdk-21 AS build
USER root
RUN microdnf install make gcc -y
COPY --chown=quarkus:quarkus mvnw /code/mvnw
COPY --chown=quarkus:quarkus .mvn /code/.mvn
COPY --chown=quarkus:quarkus pom.xml /code/
RUN mkdir /musl && \
curl -L -o musl.tar.gz https://more.musl.cc/11.2.1/x86_64-linux-musl/x86_64-linux-musl-native.tgz && \
tar -xvzf musl.tar.gz -C /musl --strip-components 1 && \
curl -L -o zlib.tar.gz https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz && \
mkdir zlib && tar -xvzf zlib.tar.gz -C zlib --strip-components 1 && \
cd zlib && ./configure --static --prefix=/musl && \
make && make install && \
cd .. && rm -rf zlib && rm -f zlib.tar.gz && rm -f musl.tar.gz
ENV PATH="/musl/bin:${PATH}"
USER quarkus
WORKDIR /code
RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.8.1:go-offline
COPY src /code/src
RUN ./mvnw package -Dnative -DskipTests -Dquarkus.native.additional-build-args="--static","--libc=musl"
## Stage 2 : create the final image
FROM scratch
COPY --from=build /code/target/*-runner /application
EXPOSE 8080
ENTRYPOINT [ "/application" ]
scratch イメージを厳密なテストなしに実稼働環境で使用しないでください。
| native-image 実行ファイルの要件 (およびネイティブイメージ圧縮を使用する場合は UPX) を満たすために、musl と zlib のバージョンを更新する必要がある場合があります。 |
ネイティブイメージの圧縮
Quarkus は、UPX を使用して生成されたネイティブ実行ファイルを圧縮できます。詳細は UPX 圧縮のドキュメント を参照してください。
Java コンパイルとネイティブイメージコンパイルの分離
特定の状況下では、ネイティブイメージを別個のステップでビルドしたい場合があります。例えば、CI/CD パイプラインにおいて、ネイティブイメージ生成に使用されるソースを生成するステップと、それらのソースを使用して実際にネイティブ実行ファイルをビルドする別のステップを設けたい場合などです。このユースケースでは、追加フラグ quarkus.native.sources-only=true を設定できます。これにより、ネイティブコンパイルを開始したかのように (-Dnative) Java コンパイルが実行されますが、GraalVM の native-image の実際の呼び出しがトリガーされる前に停止します。
$ ./mvnw clean package -Dnative -Dquarkus.native.sources-only=true
コンパイルが終了すると、target/native-sources にビルドアーティファクトが見つかります。
$ cd target/native-sources
$ ls
getting-started-1.0.0-SNAPSHOT-runner.jar graalvm.version lib native-image.args
上記の出力からわかるように、生成された JAR ファイルと関連する lib ディレクトリーに加えて、native-image.args という名前のテキストファイルが作成されています。このファイルには、GraalVM の native-image コマンドに渡すすべてのパラメーター (コンパイルする JAR の名前を含む) が保持されています。また、graalvm.version という名前のテキストファイルも作成され、使用すべき GraalVM のバージョンが保持されています。GraalVM がインストールされており、このバージョンと一致する場合は、以下を実行してネイティブコンパイルを開始できます。
$ cd target/native-sources
$ native-image $(cat native-image.args)
...
$ ls
native-image.args
getting-started-1.0.0-SNAPSHOT-runner
getting-started-1.0.0-SNAPSHOT-runner.build_artifacts.txt
getting-started-1.0.0-SNAPSHOT-runner.jar
Gradle のプロセスも同様です。
コンテナー内でビルドプロセスを実行することも可能です。
$ ./mvnw clean package -Dquarkus.native.enabled=true -Dquarkus.native.sources-only=true -Dquarkus.native.container-build=true
-Dquarkus.native.container-build=true は、ネイティブイメージのビルドに使用される Docker イメージ名を保持する native-builder.image という名前の追加のテキストファイルを生成します。
cd target/native-sources
docker run \
-it \
--user $(id -ur):$(id -gr) \
--rm \
-v $(pwd):/work \(1)
-w /work \(2)
--entrypoint /bin/sh \
$(cat native-builder.image) \(3)
-c "native-image $(cat native-image.args) -J-Xmx4g"(4)
| 1 | ホストのディレクトリー target/native-image をコンテナーの /work にマウントします。これにより、生成されたバイナリーもこのディレクトリーに書き込まれます。 |
| 2 | 作業ディレクトリーを、<1> でマウントした /work に切り替えます。 |
| 3 | ファイル native-builder.image に記載されている docker イメージを使用します。 |
| 4 | ファイル native-image.args の内容を引数として native-image を呼び出します。また、プロセスの最大メモリーを 4GB に制限する追加引数も指定しています (これは、ビルド対象のプロジェクトやビルドを行うマシンによって異なる場合があります)。 |
|
Windows マシンで実行している場合は、バイナリーが Linux docker コンテナー内で作成されたことに注意してください。したがって、そのバイナリーはホストの Windows マシンでは実行できません。 |
CI/CD パイプラインの各ステップがどのようになるかのハイレベルな概要は以下の通りです。
-
./mvnw …コマンドを実行するステップの出力 (すなわちtarget/native-imageディレクトリー) をビルドアーティファクトとして登録します。 -
native-image …コマンドを実行するステップでこのアーティファクトを要求します。そして、 -
native-image …コマンドを実行するステップの出力 (すなわちtarget/*runnerに一致するファイル) をビルドアーティファクトとして登録します。
ステップ 1 を実行する環境には Java と Maven (または Gradle) のインストールのみが必要ですが、ステップ 3 を実行する環境には GraalVM のインストール (native-image 機能を含む) のみが必要です。
CI/CD パイプラインの最終的な目的の出力に応じて、生成されたバイナリーを使用してコンテナーイメージを作成することができます。
ネイティブ実行ファイルのデバッグ
ネイティブ実行ファイルは、gdb などのツールを使用してデバッグできます。これを可能にするには、デバッグシンボル付きでネイティブ実行ファイルを生成する必要があります。
| デバッグシンボルの生成は Linux でのみサポートされています。Windows サポートは開発中であり、macOS はサポートされていません。 |
デバッグシンボルを生成するには、ネイティブ実行ファイルの生成時に -Dquarkus.native.debug.enabled=true フラグを追加します。ネイティブ実行ファイルのデバッグシンボルは、実行ファイルと同じ場所にある .debug ファイルにあります。
|
|
デバッグシンボル以外に、-Dquarkus.native.debug.enabled=true フラグを設定すると、ネイティブ実行ファイルの生成中に解決された JDK ランタイムクラス、GraalVM クラス、およびアプリケーションクラスのソースファイルのキャッシュが生成されます。このソースキャッシュは、シンボルと一致するソースコードの間のリンクを確立するために、ネイティブデバッグツールにとって有用です。これは、ネイティブ実行ファイルをデバッグする際に、必要なソースのみをデバッガーや IDE で利用可能にする便利な方法を提供します。
Quarkus のソースコードを含む、サードパーティーの JAR 依存関係のソースは、デフォルトではソースキャッシュに追加されません。これらを含めるには、まず mvn dependency:sources を呼び出してください。これらの依存関係のソースを取得し、ソースキャッシュに含めるために、この手順が必要になります。
ソースキャッシュは target/sources フォルダーにあります。
|
( または、次のように
例:
|
ネイティブイメージのデバッグに関するより詳細なガイドについては、 Native Reference ガイド を参照してください。
モニタリングオプションの使用
JDK Flight Recorder、jvmstat、ヒープドンプ、NMT (JDK 23 用の Mandrel 24.1 から)、リモート JMX などのモニタリングオプションをネイティブ実行ファイルのビルドに追加できます。ビルド時に含めたいモニタリングオプションをカンマ区切りのリストで指定するだけです。
-Dquarkus.native.monitoring=<comma separated list of options>
| モニタリングオプション | 説明 | 利用可能時期 |
|---|---|---|
jcmd |
JCMD サポートを含める |
JDK 24 用 GraalVM CE / Mandrel 24.2 |
jfr |
JDK Flight Recorder サポートを含める |
GraalVM CE 21.3 / Mandrel 21.3 |
jvmstat |
jvmstat サポートを追加 |
GraalVM 22.3、GraalVM CE 17.0.7 Mandrel 22.3 Mandrel 23.0 (17.0.7) |
heapdump |
ヒープダンプ生成のサポートを追加 |
GraalVM 22.3、GraalVM CE 17.0.7 Mandrel 22.3 Mandrel 23.0 (17.0.7) |
jmxclient |
JMX サーバーへの接続サポートを追加 |
GraalVM for JDK 17/20 Mandrel 23.0 |
jmxserver |
JMX クライアントからの接続受け入れのサポートを追加 |
GraalVM for JDK 17/20 Mandrel 23.0 (17.0.7) |
nmt |
ネイティブメモリトラッキングのサポートを追加 |
GraalVM for JDK 23 Mandrel 24.1 |
threaddump |
SIGQUIT/SIGBREAK 時のスレッドスタックダンプのサポートを追加 |
GraalVM for JDK 22 Mandrel 24.0 |
none |
Quarkus でデフォルトで有効になるすべてのモニタリングオプションのサポートを無効化 |
Quarkus が使用する擬似オプション |
all |
すべてのモニタリングオプションを追加 |
GraalVM 22.3、GraalVM CE 17.0.7 Mandrel 22.3 Mandrel 23.0 (17.0.7) |
これらのモニタリングオプションの詳細については、Quarkus Native リファレンスガイドを参照してください。
ネイティブイメージバンドルの作成
ネイティブイメージのビルドに必要なすべてを含むネイティブイメージバンドルを生成できます。これは、ビルドの入力内容や設定を検査するのに役立ちます。
バンドルの生成は、以下のいずれかのパラメーターを設定することで有効にできます。
| パラメーター | 説明 | デフォルト |
|---|---|---|
quarkus.native.bundle.enabled |
ネイティブイメージバンドルの生成を有効化 |
|
quarkus.native.bundle.dry-run |
ネイティブ実行可能ファイルをビルドせずにバンドルを生成 |
|
quarkus.native.bundle.name |
バンドル名を設定 |
この機能を使用するには、以下を実行します。
./mvnw package -Dnative -Dquarkus.native.bundle.enabled=true
このコマンドにより、ネイティブイメージのビルドに必要なすべてのファイルと設定が target/{project.name}-{project.version}-runner.nib に生成されます。
|
GraalVM ネイティブイメージバンドルの詳細は、 GraalVM ドキュメント を参照してください。 |
ネイティブ実行可能ファイルの設定
ネイティブ実行可能ファイルの生成方法に影響を与える、さまざまな設定オプションがあります。これらは他の設定プロパティーと同様に application.properties で提供されます。
プロパティーを以下に示します。
ビルド時に固定される設定プロパティー - 他のすべての設定プロパティーは実行時にオーバーライド可能です
Configuration property |
タイプ |
デフォルト |
||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Set to enable native-image building using GraalVM. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Set to enable native-image bundle generation. Environment variable: Show more |
ブーリアン |
|||||||||||||||||||||
Generates the native-image bundle through a dry-run build, skipping the actual native-image build. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Set to define the native-image bundle name. If not set the default name will match the native-executable’s name suffixed by Environment variable: Show more |
string |
|||||||||||||||||||||
Set to prevent the native-image process from actually building the native image. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Comma-separated, additional arguments to pass to the build process. If an argument includes the Environment variable: Show more |
文字列のリスト |
|||||||||||||||||||||
Comma-separated, additional arguments to pass to the build process. The arguments are appended to those provided through Environment variable: Show more |
文字列のリスト |
|||||||||||||||||||||
If the HTTP url handler should be enabled, allowing you to do URL.openConnection() for HTTP URLs Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If the HTTPS url handler should be enabled, allowing you to do URL.openConnection() for HTTPS URLs Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
The default value for java.awt.headless JVM option. Switching this option affects linking of awt libraries. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Defines the file encoding as in Native image runtime uses the host’s (i.e. build time) value of Environment variable: Show more |
string |
|
||||||||||||||||||||
If all character sets should be added to the native executable. Note that some extensions (e.g. the Oracle JDBC driver) also take this setting into account to enable support for all charsets at the extension level. This increases image size. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
The location of the Graal distribution Environment variable: Show more |
string |
|
||||||||||||||||||||
The location of the JDK Environment variable: Show more |
|
|||||||||||||||||||||
The maximum Java heap to be used during the native image generation Environment variable: Show more |
string |
|||||||||||||||||||||
If the native image build should wait for a debugger to be attached before running. This is an advanced option and is generally only intended for those familiar with GraalVM internals Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If the debug port should be published when building with docker and debug-build-process is true Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If isolates should be enabled Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If a JVM based 'fallback image' should be created if native image fails. This is not recommended, as this is functionally the same as just running the application in a JVM Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If all META-INF/services entries should be automatically registered Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If the bytecode of all proxies should be dumped for inspection Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If this build should be done using a container runtime. Unless container-runtime is also set, docker will be used by default. If docker is not available or is an alias to podman, podman will be used instead as the default. Environment variable: Show more |
ブーリアン |
|||||||||||||||||||||
Explicit configuration option to generate a native Position Independent Executable (PIE) for Linux. If the system supports PIE generation, the default behaviour is to disable it for performance reasons. However, some systems can only run position-independent executables, so this option enables the generation of such native executables. Environment variable: Show more |
ブーリアン |
|||||||||||||||||||||
Generate instructions for a specific machine type. Defaults to Environment variable: Show more |
string |
|||||||||||||||||||||
If this build is done using a remote docker daemon. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
The docker image to use to do the image build. It can be one of Note: Builder images are available using UBI 8 and UBI 9 base images, for example:
You need to be aware that if you use a builder image using UBI9 and you plan to build a container, you must ensure that the base image used in the container is also UBI9. Environment variable: Show more |
string |
|
||||||||||||||||||||
The strategy for pulling the builder image during the build. Defaults to 'always', which will always pull the most up-to-date image; useful to keep up with fixes when a (floating) tag is updated. Use 'missing' to only pull if there is no image locally; useful on development environments where building with out-of-date images is acceptable and bandwidth may be limited. Use 'never' to fail the build if there is no image locally. Environment variable: Show more |
|
|
||||||||||||||||||||
The container runtime (e.g. docker) that is used to do an image based build. If this is set then a container build is always done. Environment variable: Show more |
|
|||||||||||||||||||||
Options to pass to the container runtime Environment variable: Show more |
文字列のリスト |
|||||||||||||||||||||
This property is deprecated: Use If the resulting image should allow VM introspection. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Enable monitoring various monitoring options. The value should be comma separated.
Environment variable: Show more |
list of |
|||||||||||||||||||||
If the reports on call paths and included packages/classes/methods should be generated Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If exceptions should be reported with a full stack trace Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
If errors should be reported at runtime. This is a more relaxed setting, however it is not recommended as it means your application may fail at runtime if an unsupported feature is used by accident. Note that the use of this flag may result in build time failures due to `ClassNotFoundException`s. Reason most likely being that the Quarkus extension already optimized it away or do not actually need it. In such cases you should explicitly add the corresponding dependency providing the missing classes as a dependency to your project. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Don’t build a native image if it already exists. This is useful if you have already built an image and you want to use Quarkus to deploy it somewhere. Note that this is not able to detect if the existing image is outdated, if you have modified source or config and want a new image you must not use this flag. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
A comma separated list of globs to match resource paths that should be added to the native image. Use slash ( By default, no resources are included. Example: Given that you have
the files Supported glob features
Note that there are three levels of escaping when passing this option via
All three levels use backslash ( Note that Quarkus extensions typically include the resources they require by themselves. This option is useful in situations when the built-in functionality is not sufficient. Environment variable: Show more |
文字列のリスト |
|||||||||||||||||||||
This property is deprecated since A comma separated list of globs to match resource paths that should not be added to the native image. Use slash ( Please refer to By default, no resources are excluded. Example: Given that you have
the resource Environment variable: Show more |
文字列のリスト |
|||||||||||||||||||||
If debug is enabled and debug symbols are generated. The symbols will be generated in a separate .debug file. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Generate the report files for GraalVM Dashboard. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Include a reasons entries in the generated json configuration files. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Whether compression should be enabled. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Whether the compression should be executed within a container. Environment variable: Show more |
ブーリアン |
|||||||||||||||||||||
The image used for compression. Defaults to Setting this variable will automatically activate Environment variable: Show more |
string |
|||||||||||||||||||||
The compression level in [1, 10]. 10 means best. Higher compression level requires more time to compress the executable. Environment variable: Show more |
int |
|||||||||||||||||||||
Allows passing extra arguments to the UPX command line (like --brute). The arguments are comma-separated. The exhaustive list of parameters can be found in https://github.com/upx/upx/blob/devel/doc/upx.pod. Environment variable: Show more |
文字列のリスト |
|||||||||||||||||||||
Configuration files generated by the Quarkus build, using native image agent, are informative by default. In other words, the generated configuration files are presented in the build log but are not applied. When this option is set to true, generated configuration files are applied to the native executable building process. Enabling this option should be done with care, because it can make native image configuration and/or behaviour dependant on other non-obvious factors. For example, if the native image agent generated configuration was generated from running JVM unit tests, disabling test(s) can result in a different native image configuration being generated, which in turn can misconfigure the native executable or affect its behaviour in unintended ways. Environment variable: Show more |
ブーリアン |
|
||||||||||||||||||||
Enable Profile-Guided Optimization for native images. Requires Oracle GraalVM. When enabled, the native build produces an instrumented binary. Running Environment variable: Show more |
ブーリアン |
|
次のステップ
このガイドでは、アプリケーションのネイティブ (バイナリー) 実行可能ファイルの作成について説明しました。これにより、迅速な起動時間を実現し、メモリ消費を抑えたアプリケーションが提供されます。しかし、それだけではありません。
Kubernetes および OpenShift へのデプロイ を読み、学習を続けることをお勧めします。