Javaアプリケーションを自動的にコンテナイメージにビルドするツール「Jib」を使ってみた

Jib 1.0.0 が GA されたというニュースを見たので使ってみました.

Jib とは…

Jib builds optimized Docker and OCI images for your Java applications without a Docker daemon – and without deep mastery of Docker best-practices. It is available as plugins for Maven and Gradle and as a Java library.

意訳:

Jibを使うことで、Dockerデーモンなしで、そしてDockerのベストプラクティスを熟知していなくても、Javaアプリケーション用に最適化されたDockerおよびOCIイメージを構築できます. MavenとGradleのプラグインとして、そしてJavaライブラリとして利用可能です.

結構便利そうですね.

ver 1.0.0 の変更点

  • warファイル対応
  • Skaffold対応

せっかくなので war を使ったイメージ作成を試してみたいと思います.

 

設定

Maven/Gradle Plugin として使います.
今回は Maven で使ってみました.

Configuration の部分を解説します.

from タグでベースイメージを指定します.

 
to タグで生成先イメージ名を指定します.

Container Registry に公開することも出来ます.
Jib Configuration
 
appRoot タグで war のデプロイ先を指定します.

一つ気を付けなければいけないのは .war ファイルがデプロイされるのではなく、WEB-INF/META-INF がデプロイされることです.

.war をデプロイする機能も検討されていますが、まだ実装されていません.
Explode WAR instead of working on exploded WAR directory for Maven
 
extraDirectory タグで他のファイルを追加します.

path タグで追加したファイルを置くディレクトリを指定します.
以下のように、jibディレクトリ配下に Container 側のディレクトリ階層に合わせてファイルを配置します.

├── jib
│    └── opt
│        └── jboss
│            └── wildfly
│                └── standalone
│                    └── deployments
│                        └── demoapi.war.dodeploy

Wildfly は展開形式のWEBアプリケーションはデフォルトで自動デプロイするようにはなっていないので、デプロイを通知する .dodeploy ファイルを配置するようにしました.
WildFlyにアプリケーションをデプロイする

 

コンテナビルド&起動

mav package で Docker イメージをビルドしてみます.

$ mvn package jib:dockerBuild
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------< com.example:demoapi >-------------------------
[INFO] Building demoapi 0.0.1-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-war-plugin:3.2.2:war (default-war) @ demoapi ---
[INFO] Packaging webapp
[INFO] Assembling webapp [demoapi] in [/Users/Daiki/Desktop/prototype/target/demoapi-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/Daiki/Desktop/prototype/src/main/webapp]
[INFO] Webapp assembled in [841 msecs]
[INFO] Building war: /Users/Daiki/Desktop/prototype/target/demoapi-0.0.1-SNAPSHOT.war
[INFO] 
[INFO] --- jib-maven-plugin:1.0.0:dockerBuild (default-cli) @ demoapi ---
[INFO] 
[INFO] Containerizing application to Docker daemon as wildfly-prototype:jib...
[INFO] The base image requires auth. Trying again for jboss/wildfly:15.0.0.Final...
[INFO] Container program arguments set to [/opt/jboss/wildfly/bin/standalone.sh, -b, 0.0.0.0] (inherited from base image)
[INFO] 
[INFO] Built image to Docker daemon as wildfly-prototype:jib
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:14 min
[INFO] Finished at: 2019-02-16T22:30:02+09:00
[INFO] ------------------------------------------------------------------------

 
ちゃんとイメージが生成出来ています.

$ docker images
REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
jboss/wildfly                              latest              2602b4852593        5 weeks ago         675MB
wildfly-prototype                          jib                 6d772cd886f0        49 years ago        786MB

タイムスタンプはおかしいことになってますね…

生成したイメージを起動してみます.

$ docker-compose up

prototype   | =========================================================================
prototype   | 
prototype   |   JBoss Bootstrap Environment
prototype   | 
prototype   |   JBOSS_HOME: /opt/jboss/wildfly
prototype   | 
prototype   |   JAVA: /usr/lib/jvm/java/bin/java
prototype   | 
prototype   |   JAVA_OPTS:  -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true  --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED --add-modules=java.se
prototype   | 
prototype   | =========================================================================
prototype   | 
prototype   | 11:15:17,158 INFO  [org.jboss.modules] (main) JBoss Modules version 1.8.7.Final

prototype   | 11:15:36,209 INFO  [stdout] (ServerService Thread Pool -- 81) 
prototype   | 11:15:36,373 INFO  [org.hibernate.validator.internal.util.Version] (background-preinit) HV000001: Hibernate Validator 6.0.13.Final
prototype   | 11:15:37,125 INFO  [stdout] (ServerService Thread Pool -- 81) 
prototype   | 11:15:37,128 INFO  [stdout] (ServerService Thread Pool -- 81)   .   ____          _            __ _ _
prototype   | 11:15:37,129 INFO  [stdout] (ServerService Thread Pool -- 81)  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
prototype   | 11:15:37,130 INFO  [stdout] (ServerService Thread Pool -- 81) ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
prototype   | 11:15:37,134 INFO  [stdout] (ServerService Thread Pool -- 81)  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
prototype   | 11:15:37,135 INFO  [stdout] (ServerService Thread Pool -- 81)   '  |____| .__|_| |_|_| |_\__, | / / / /
prototype   | 11:15:37,137 INFO  [stdout] (ServerService Thread Pool -- 81)  =========|_|==============|___/=/_/_/_/
prototype   | 11:15:37,144 INFO  [stdout] (ServerService Thread Pool -- 81)  :: Spring Boot ::        (v2.1.2.RELEASE)
prototype   | 11:15:37,146 INFO  [stdout] (ServerService Thread Pool -- 81) 
prototype   | 11:15:37,428 INFO  [com.example.demoapi.DemoApiApplication] (ServerService Thread Pool -- 81) Starting DemoApiApplication on 3ccaade69904 with PID 80 (/opt/jboss/wildfly/standalone/deployments/demoapi.war/WEB-INF/classes started by root in /opt/jboss)
prototype   | 11:15:37,434 INFO  [com.example.demoapi.DemoApiApplication] (ServerService Thread Pool -- 81) No active profile set, falling back to default profiles: default
prototype   | 11:15:37,529 INFO  [org.springframework.boot.devtools.env.DevToolsPropertyDefaultsPostProcessor] (ServerService Thread Pool -- 81) For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'

ちゃんと立ち上がりました.

 

感想

Maven から Docker をキックできるのは結構便利だなと思いました.
ただ必須かと言うと、別に Dockerfile を書くのでもいいかなと個人的には思ったりします.

使いどころを考えると、

  • アプリチームでコンテナ化まで全て完結させたいとき
  • CI/CD において、Maven コマンド一発で Container Registry への登録まで行いたいとき

こんな感じでしょうか.

Dockerfile を管理しない弊害が何か出ないかな?とかはちょっと気になりますが、CI/CD で使ってみたいです.

 

以上です.