docs community blog github
Edit

Paketo Buildpacks で Java アプリケーションをビルドする

このドキュメントでは Paketo Buildpack を使用して Java アプリケーションのコンテナイメージを作成する方法を説明します。 Buildpack の振る舞いや設定方法を詳しく知りたいときは、Paketo Java BuildpackPaketo Java Native Image Buildpack のリファレンスを参照してください。

サンプルアプリをビルドする

このドキュメントでは Paketo Buildpacs サンプルアプリ を使用します。

それぞれの例では、リポジトリ直下を作業ディレクトリとしています。

git clone https://github.com/paketo-buildpacks/samples
cd samples
copy to clipboard
Copied!

pack コマンド も使用します。 pack は Java Buildpack でビルドを実行できる Cloud Native Buildpack [platform][platform] の1つです。 例えば、Spring Boot アプリケーションの開発者なら Spring Boot Maven PluginSpring Boot Gradle Plugin を使用できます。

それぞれの例では、 Paketo Base ビルダー を初期値にしています。

pack config default-builder paketobuildpacks/builder:base
copy to clipboard
Copied!

Java アプリケーションのサンプルは、どれも actuator health endpoint{"status":"UP"} を返すようになっています。

docker run --rm --tty --publish 8080:8080 samples/java
curl -s http://localhost:8080/actuator/health | jq .
copy to clipboard
Copied!

ソースコードからビルドする

Java Buildpack は次のようなビルドツールでソースコードをビルドできるようになっています。

使用するビルドツールはアプリケーションディレクトリの内容に基づいて検出します。

ビルド処理は 対応しているいずれかの形式のアーティファクト を生成しなければなりません。 完了すると、buildpack は展開したアーカイブの内容でアプリケーションのソースコードを置き換えます。 その後の処理については コンパイル済みアーティファクトからのビルド を参照してください。

:Maven でビルドする

次のコマンドは Maven プロジェクトのソースコードからコンテナイメージを作成します。

pack build samples/java \
  --path java/maven
copy to clipboard
Copied!

ビルドツールを設定する

注意:以降の内容は全ての設定項目を網羅したものではありません。設定項目について、詳しくはビルドツールに対応する Buildpack のリファレンスを参照してください。

モジュールやアーティファクトを選択する

以降の説明に登場する <TOOL> には MAVENGRADLELEINSBT のいずれかで置き換えることになります。 モジュールやアーティファクトを選択するには、次のような環境変数をビルド時に指定します。

  • BP_<TOOL>_BUILT_MODULE
    • 初期値 はルートモジュールです。
    • マルチモジュールプロジェクトにおいて、Buildpack がアーティファクトをビルドするモジュールを選択します。
    • BP_MAVEN_BUILT_MODULE=api と指定すると、Paketo Maven Buildpack は target/api/*.[jw]ar に対応するファイル名のアーティファクトを選択します。
  • BP_<TOOL>_BUILT_ARTIFACT
    • 初期値はビルドツールによって異なります(Maven なら target/*.[jw]ar、Gradle なら build/libs/*.[jw]ar)。ビルドツールに対応する Buildpack のリファレンスを参照してください。
    • アーティファクトを探索するパス名のパターンを [Bashのパターンマッチ](bash pattern matching) で指定します。
    • BP_<TOOL>_BUILT_MODULE に初期値以外が設定されているとしても、こちらの設定を優先します。
    • BP_MAVEN_BUILT_ARTIFACT=out/api-*.jar と指定すると、Paketo Maven Buildpack は out/api-1.0.0.jar を発見します。

ビルドコマンドを指定する

以降の説明に登場する <TOOL> には MAVENGRADLELEINSBT のいずれかで置き換えることになります。 モジュールやアーティファクトを選択するには、次のような環境変数をビルド時に指定します。

  • BP_<TOOL>_BUILD_ARGUMENTS
  • 初期値:ビルドツールによって異なります(Maven なら -Dmaven.test.skip=true package、Gradle なら --no-daemon assemble)。ビルドツールに対応する Buildpack のリファレンスを参照してください。
  • 指定した値がビルドツールのコマンドの引数になります。
  • BP_GRADLE_BUILD_ARGUMENTS=war と指定すると、Paketo Gradle Buildpack は ./gradlew wargradle war を実行します(Gradle Wrapper の有無によって変化します)。

プライベート Maven リポジトリを使用する

maven バインディング のキーに settings.xml を指定すると、独自の Maven settings を使用できます。

<binding-name>
├── settings.xml
└── type

settings.xml ファイルには、プライベート Maven リポジトリへ接続するための資格情報を記述できます。

: 独自の Maven Settings を構成する

作業 PC の settings.xml を使用して、pack コマンドでアプリケーションをビルドする手順を説明します。

  1. バインディングリソースを格納するディレクトリを作成します。
    mkdir java/maven/binding
    copy to clipboard
    Copied!
  1. 作成したディレクトリに、バインディング種類 maven を含む type ファイルを作成します。
    echo -n "maven" > java/maven/binding/type
    copy to clipboard
    Copied!
  1. 作成したディレクトリに、作業PCの settings.xml を複製します。
    cp ~/.m2/settings.xml java/maven/binding/settings.xml
    copy to clipboard
    Copied!
  1. 作成したディレクトリを、pack build コマンドの --volume フラグに指定します。
    pack build samples/java \
       --path java/maven \
       --volume $(pwd)/java/maven/binding:/platform/bindings/my-maven-settings
    copy to clipboard
    Copied!

コンパイル済みアーティファクトからビルドする

Buildpack を利用するアプリケーション開発者は、次のようなアーカイブ(の形式)からコンテナイメージをビルドできます。

Java Buildpack はアーカイブを展開した場所をアプリケーションディレクトリとして扱います。 指定されたアーカイブが何であれ、ほとんどのプラットフォームでは自動的に展開します。

Java Buildpack は war ファイルを検出すると Apache Tomcat(apache tomcat) をインストールします。 Java Buildpack の使用する Tomcat のバージョンについては、Paketo Java Buildpack のリリースノート を参照してください。 Tomcat の設定項目については Apache Tomcat Buildpack を参照してください。

指定したアーティファクトの形式に対応する Buildpack は、作成するコンテナイメージの起動コマンドを指定してくれます。

注意:アーティファクトの形式に応じて、 Apache Tomcat BuildpackExecutable Jar BuildpackDist Zip Buildpack の3種類から1つ以上の Buildpack を選択します。しかし、最終的なコンテナイメージを作成するのはどれか1つの Buildpack です。ソースコードからビルドした場合 等、アーティファクトの形式を検出できない場合があります。

:実行可能 jar ファイルをビルドする

Maven でビルドした実行可能 jar ファイルを使用して、pack コマンドでアプリケーションをビルドするには、次のように実行します。

cd java/maven
./mvnw package
pack build samples/java \
   --path /target/demo-0.0.1-SNAPSHOT.jar
copy to clipboard
Copied!

作成したコンテナイメージは、「Maven でビルドする」でビルドしたイメージと同じになっているはずです。

JVM のバージョンを確認する

作成したコンテナイメージに含まれる正確な JRE のバージョンは、BOM(Bill-of-Materials) から読み取ることができます。

JRE のバージョンを確認する

サンプルプロジェクトから作成したコンテナイメージ samples/java について、インストールされている JRE のバージョンを表示するには、次のように実行します。

pack inspect-image samples/app --bom | jq '.local[] | select(.name=="jre") | .metadata.version'
copy to clipboard
Copied!

JVM のインストールするバージョンを指定する

JVM のバージョンを指定するときは、ビルド時に次の環境変数を指定します。

  • BP_JVM_VERSION
    • 初期値は、Buildpack をリリースした時点で最新の LTS バージョンです。
    • JDK あるいは JRE のバージョンを指定します。
    • BP_JVM_VERSION=8 あるいは BP_JVM_VERSION=8.* とした場合、Buildpack は Java 8 の JDK あるいは JRE の、最新のパッチリリースをインストールします。

JVM の動作を変更する

Java Buildpack では環境変数 JAVA_TOOL_OPTIONS で JVM の動作を調整するようになっています。

JVM の動作を調整する方法は2種類あります。

  1. Buildpack の提供する実行時コンポーネントのメモリー設定計算機が使用する、次のような環境変数を指定します。これらの値は最終的に JAVA_TOOL_OPTIONS へ設定する内容を算出するために使用されます。
    • BPL_JVM_HEAD_ROOM
    • BPL_JVM_LOADED_CLASS_COUNT
    • BPL_JVM_THREAD_COUNT
  2. 直接 JAVA_TOOL_OPTIONS を指定します。ユーザーの指定した内容は Buildpack の構成した内容の最後に追加されます。同じ項目を指定した場合、ユーザーの指定した値を優先します。

全ての設定項目については Bellsoft Liberica Buildpack のリファレンス を参照してください。

別の JVM を使用する

初期設定の Paketo Java Buildpack は Liberica JVM を使用します。 Liberica の代わりに使用できる JVM (と対応する Buildpack) は次のとおりです。

JVM Buildpack
Alibaba Dragonwell Paketo Alibaba Dragonwell Buildpack
Amazon Corretto Paketo Amazon Corretto Buildpack
Azul Zulu Paketo Azul Zulu Buildpack
BellSoft Liberica Paketo BellSoft Liberica Buildpack - Default
Eclipse OpenJ9 Paketo Eclipse OpenJ9 Buildpack
GraalVM Paketo GraalVM Buildpack
Microsoft OpenJDK Paketo Microsoft OpenJDK Buildpack
SapMachine Paketo SapMachine Buildpack

別の JVM を使用するときは、pack build コマンドに2つの --buildpack フラグを指定しなければなりません。 最初に JVM Buildpack を指定し、次に Paketo Java Buildpack を指定します(順番が重要です)。 そうすると、pack build は2つの JVM Buildpack を使用することになるのですが、最初に指定した Buildpack がビルドプランの要素として登録され、後に指定した Buildpack は何もしない状態になります。

次の例は Azul Zulu Buikdpack を使用しています。

pack build samples/jar \
    --buildpack gcr.io/paketo-buildpacks/azul-zulu \
    --buildpack paketo-buildpacks/java
copy to clipboard
Copied!

この方法には1つ欠点があります。 CA Certs Buildpack より先に JVM Buildpack を取得するので、JVM ベンダーの提供するコンテンツを取得するとき、CA 証明局は最新化されておらず、信頼できないコンテンツを取得してしまう場合があるのです。 ですが、ほとんどのユーザーには影響しないものだと考えています。 ほとんどの JVM Buildpack はデフォルトのシステムトラストストアに含まれている CA が書名した証明書を使用するURL(ドメイン)で提供されているはずだからです。

カスタマイズした JVM Buildpack を、既存の CA 認証局が署名してない証明書を使用する URL からダウンロードさせるときは、最初に CA Certs Buildpack を実行するといいでしょう。 CA Cert Buildpack を重複して実行することになりますが、ライフサイクルは2回目の実行を無視できるくらい簡潔なままです。

具体的には次のように実行します。

pack build samples/jar \
    --buildpack paketo-buildpacks/ca-certificates \
    --buildpack gcr.io/paketo-buildpacks/azul-zulu \
    --buildpack paketo-buildpacks/java
copy to clipboard
Copied!

常にこのような使い方をしていても、メッセージや処理が冗長になるだけで特に問題はありません。 また、ほとんどのユーザーは CA Cert Buildpack を先頭にしなくても問題になりません。

別の Native Image Toolkit を使用する

初期設定の [Paketo Java Native Image Buildpack][bp/java-ntive-image] は GraalVM Native Image Toolkit を使用します。 代わりに使用できる Native Image Toolkit (と対応する Buildpack) は次のとおりです。

JVM Buildpack
Bellsoft Liberica Paketo Bellsoft Liberica Buildpack

別の Java Native Image Toolkit を使用するときは、pack build コマンドに2つの --buildpack フラグを指定しなければなりません。 最初に Java Native Image Toolkit Buildpack を指定し、次に Paketo Java Native Image Buildpack を指定します(順番が重要です)。 そうすると、pack build は2つの Native Image Toolkit Buildpack を使用することになるのですが、最初に指定した Buildpack がビルドプランの要素として登録され、後に指定した Buildpack は何もしない状態になります。

Bellsoft Liberica Buildpack を使う場合は次のように実行します。

pack build samples/native-image \
    --buildpack paketo-buildpacks/bellsoft-liberica \
    --buildpack paketo-buildpacks/java-native-image
copy to clipboard
Copied!

Spring Boot アプリケーションをビルドする

Spring Boot アプリケーションの依存ライブラリを確認する

次のコマンドを実行すると、サンプルアプリケーションで作成したコンテナイメージの依存ライブラリを確認できます。

pack inspect-image samples/java --bom | \
jq '.local[] | select(.name=="dependencies") | .metadata.dependencies[].name'
copy to clipboard
Copied!

Spring Boot の自動構成を無効にする

Spring Boot Buildpack はクラスパスに Spring Cloud Bindings を追加します。 Spring CloudBindings は、バインディングに配置した資格情報と接続設定に基づいて、外部サービスへ接続するための設定を、実行時に自動的に構成します。 初期設定で自動構成機能は有効になっていますが、環境変数 BPL_SPRING_CLOUD_BINDINGS_ENABLED を指定すると無効にできます。

APM へ接続する

Java Buildpack は次のような APM と連携できるようになっています。

APM 連携機能は バインディング で有効にします。 ビルド時に適切なバインディング種類が存在する場合、対応する Java エージェントをコンテナイメージに埋め込みます。 APM へ接続するための資格情報は、実行時にバインディングから読み取ります。

:Azure Application Insights に接続する

次のコマンドは、Azure Application Insights の Java エージェントをコンテナイメージに埋め込みます。

pack build samples/java \
    --volume "$(pwd)/java/application-insights/binding:/platform/bindings/application-insights"
copy to clipboard
Copied!

アプリケーションが Azure Application Insights へ接続するには正式な Instrumentation Key が必要です。

echo "<Instrumentation Key>" > java/application-insights/binding/InstrumentationKey
docker run --rm --tty \
  --env SERVICE_BINDING_ROOT=/bindings \
  --volume "$(pwd)/java/application-insights/binding:/bindings/app-insights" \
  samples/java
copy to clipboard
Copied!

リモートデバッグを有効にする

ビルド時に環境変数 BP_DEBUG_ENABLED を指定すると、 Debug Buildpack により、Java アプリケーションがデバッグ接続を待ち受けるように設定します。 そして、実行時に環境変数 BPL_DEBUG_ENABLED を指定すると、Java アプリケーションがデバッグ接続を待ち受けるようになります。 デバッグ接続用の TCP ポート番号の初期値は 8000 ですが、実行時に環境変数 BPL_DEBUG_PORT で変更できます。 実行時に環境変数で BPL_DEBUG_SUSPEND を指定すると、デバッガがアタッチするまで JVM プロセスは実行を中断するようになります。

:リモートデバッグ

リモートデバッグできるコンテナイメージを作成するには次のように実行します。

pack build samples/java \
  --path java/jar \
  --env BP_DEBUG_ENABLED=true
copy to clipboard
Copied!

デバッグ接続用の TCP ポートを公開するには次のようにコンテナイメージを実行します。

docker run --env BPL_DEBUG_ENABLED=true --publish 8000:8000 samples/java
copy to clipboard
Copied!

IDE のデバッガで公開した TCP ポートに接続できます。

Eclipse Remote Debug Configuration

JMX を有効にする

ビルド時に環境変数 BP_JMX_ENABLED を指定すると、 JMX BuildpackJMX を有効にします。 そして、実行時に環境変数 BPL_JMX_ENABLED を指定すると、Java アプリケーションへ JMX で接続できるようになります。 JMX 接続に使用する TCP ポート番号の初期値は 5000 ですが、環境変数 BPL_JMX_PORT で変更できます。

: JMX を有効にする

JMX 接続できるコンテナイメージを作成するには次のように実行します。

pack build samples/java \
  --path java/jar \
  --env BP_JMX_ENABLED=true
copy to clipboard
Copied!

JMX 接続用の TCP ポートを公開するには次のようにコンテナイメージを実行します。

docker run --env BPL_JMX_ENABLED=true --publish 5000:5000 samples/java
copy to clipboard
Copied!

JConsole で公開した TCP ポートに接続できます。

JConsole

コンテナイメージの起動コマンドに引数を追加する

コンテナイメージの CMD に、起動コマンドの引数を追加できます。 Kubernetes では container リソースの args フィールドへ指定します。

: サーバーポート番号を指定する

アプリケーションの起動コマンドの引数で、待ち受けポート番号として 8081 を指定するには次のように実行します。

docker run --rm --publish 8081:8081 samples/java --server.port=8081
curl -s http://localhost:8081/actuator/health
copy to clipboard
Copied!

コンテナイメージの起動コマンドを指定する

Buildpack の構成した起動コマンドは、コンテナイメージの ENTRYPOINT で変更できます。

: 対話形式のシェルを実行する

対話形式で Bash を起動するには次のように実行します。

docker run --rm --entrypoint bash samples/java
copy to clipboard
Copied!

Buildpack の構成した環境で指定したコマンドを実行する

Buildpack で作成したコンテナイメージには、実行可能ファイル launcher が必ず存在します。 このファイルは、Buildpack の構成する環境変数を設定した状態で指定したコマンドを実行するために使用できます。 launcher は指定したコマンドを実行する前に、Buildpack の配置した全てのプロファイルスクリプトを実行します。 環境変数の値を実行時に計算するためです。

コンテナイメージの ENTRYPOINTlauncher を指定し、CMD に実行したいコマンドを指定すれば、Buildpack の構成した環境で指定したコマンドを実行できます。

: Buildpack の構成した JAVA_TOOL_OPTIONS を確認する

Buildpack の構成した JAVA_TOOL_OPTIONS の値を表示するには次のように実行します。

docker run --rm --entrypoint launcher samples/java echo 'JAVA_TOOL_OPTIONS: $JAVA_TOOL_OPTIONS'
copy to clipboard
Copied!

launcher に指定したコマンドは実行前にシェルで評価しますが、元のトークン区切りを保持します。 例えば、'JAVA_TOOL_OPTIONS: $JAVA_TOOL_OPTIONS' という文字列はシングルクォートで囲まれているため、$JAVA_TOOL_OPTIONS の部分はホストのシェルではなく、コンテナ上で評価されます。

アプリケーションを GraalVM のネイティブイメージとしてビルドする

Paketo Java Native Image Buildpack は、GraalVMnative image でビルドしたアプリケーションを含む、コンテナイメージを作成します。

Java Native Buildpack は 合成 Buildpack です。 build コマンドのそれぞれの段階は、それぞれの コンポーネント が制御するようになっています。 以降の説明では、基本的な設定項目を説明します。 全ての設定項目や、利用できる機能については対応するコンポーネント(Buildpack)のリファレンスを参照してください。

ソースコードからビルドする

Java Native Image Buildpack では Java Buildpack と同じ ビルドツールや設定項目 を使用できます。 ただし、実行可能形式のjarファイル を生成しなければなりません。

Buildpack はコンパイルとパッケージングを完了すると、作成した jar ファイルを展開してアプリケーションのソースコードを置き換えます。 そして、 [実行可能形式の jar ファイルからビルド][building-from-an-executable-jar] します。

: Maven で Native Image をビルドする

次のコマンドは Maven プロジェクトのソースコードからコンテナイメージを作成します。

pack build samples/java-native \
  --env BP_NATIVE_IMAGE=true \
  --path java/native-image/java-native-image-sample
copy to clipboard
Copied!

実行可能形式の jar ファイルからビルドする

実行可能形式の jar ファイル を展開する方法でコンテナイメージを作成できます。 ほとんどのプラットフォームは指定されたファイルのアーカイブ形式を自動的に判断し、展開できます。

:実行可能形式の jar ファイルから Native Image をビルドする

Maven プロジェクトのソースコードからビルドした実行可能形式の jar ファイルを pack コマンドに指定して、コンテナイメージを作成するときは次のように実行します。

cd samples/java/native-image
./mvnw package
pack build samples/java-native \
  --env BP_NATIVE_IMAGE=true \
  --path java/native-image/java-native-image-sample/target/demo-0.0.1-SNAPSHOT.jar
copy to clipboard
Copied!

作成したコンテナイメージは「Maven で Native Image をビルドする」でビルドしたイメージと同じになっているはずです。

JVM のバージョンを確認する

作成したコンテナイメージに含まれる正確な Substrate VM のバージョンは、BOM(Bill-of-Materials) から読み取ることができます。

JRE のバージョンを確認する

サンプルプロジェクトから作成したコンテナイメージ samples/java-native について、インストールされている Substrate VM のバージョンを表示するには、次のように実行します。

pack inspect-image samples/java-native --bom | \
jq '.local[] | select(.name=="native-image-svm") | .metadata.version'
copy to clipboard
Copied!

GraalVM のバージョンを指定する

GraalVM は急速に進歩しているので、互換性を保証しなければならない場合は、コンテナイメージをビルドする GraalVM や関連するツールのバージョンを指定するといいでしょう。 JVM のバージョンのように直接指定することはできないのですが、代わりに Java Native Image Buildpack のバージョンを指定すれば、対応する GraalVM のバージョンを指定できます。

GraalVM と Java Native Image Buildpack のバージョンの対応関係は次のとおりです。

GraalVM Version Java Native Image Buildpack Version
21.2 5.5.0
21.1 5.4.0
21.0 5.3.0

GraalVM 21.1 を使用するには次のように実行します。

pack build samples/native \
    -e BP_NATIVE_IMAGE=true \
    --buildpack gcr.io/paketo-buildpacks/ca-certificates \
    --buildpack gcr.io/paketo-buildpacks/java-native-image:5.4.0
copy to clipboard
Copied!
Edit

Last modified: September 13, 2021