Zenn
🐳

Jibを使ったJava,Kotlinアプリケーションの簡単&最適Docker化

に公開

はじめに

こんにちは!ispecでエンジニアをしているほりです!

弊社では、バックエンドにKotlinを採用して開発を行っています。今回は、JavaやKotlinで実装したアプリケーションを、DockerやJVMの深い知識がなくても簡単に最適にDocker化できるJibをご紹介します。

Jibとは?

Jib

https://github.com/GoogleContainerTools/jib

Jibは、JavaやKotlinアプリケーションをDockerイメージに変換するための、GradleおよびMavenプラグインです。以下の特徴があります。

Dockerfileが不要

Jibの最大の魅力は、Dockerfileを作成する必要がないことです。Maven/Gradleのプラグインとして動作し、ビルドプロセスの一部としてコンテナイメージを生成します。

Docker環境が不要

通常のDockerイメージビルドではDocker環境が必要ですが、JibはローカルにDockerをインストールしなくても動作します。

高速なビルド

Jibはアプリケーションを、依存関係、リソース、クラスファイル等にレイヤー化し効率的にキャッシュしています。これにより差分ビルドが可能となり、ビルド時間が大幅に短縮されます。

最適化されたコンテナイメージ

Jibで生成されたイメージは、コンテナに求められるベストプラクティスに従った構造になっています。

レジストリへのプッシュ

Jibは、Docker HubやGoogle Artifact Registry、Amazon ECRなどのレジストリに直接イメージをプッシュすることができます。これにより、CI/CDパイプラインでの統合が容易になります。

簡単な設定

Maven/Gradleの設定ファイルに少量の設定を追加するだけで使用可能です。

簡単3ステップでDocker化

まずはローカル環境で、最低限の設定でイメージを作成してみます。

1. プラグインの追加

GradleプロジェクトにJibプラグインを追加します。

build.gradle.kts
plugins {
    kotlin("jvm") version "2.1.20"
    id("io.ktor.plugin") version "3.1.1"
+    id("com.google.cloud.tools.jib") version "3.4.5"
}

2. イメージのビルド

以下のコマンドを実行するだけでDockerイメージが作成されます。

./gradlew jibDockerBuild

3. コンテナの実行

作成されたイメージを実行します。

docker run --rm -p 8080:8080 jib-containerize-demo:0.0.1

これだけで、アプリケーションがコンテナ化され、実行できる状態になりました!

Jibの高度な設定

デフォルト設定でも十分使えますが、必要に応じてカスタマイズも可能です。

設定可能な項目はこちらからご確認ください。
https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage

jib {
    from {
        image = "adoptopenjdk/openjdk11:alpine-jre"
    }
    to {
        image = "my-docker-registry/my-app:${project.version}"
    }
    container {
        ports = listOf("8080")
        environment = mapOf(
            "SPRING_PROFILES_ACTIVE" to "production"
        )
        jvmFlags = listOf("-Xms512m", "-Xmx1g")
    }
}

GitHub ActionsでECRにアップロードする例

CI/CDパイプラインにJibを統合することも簡単です。以下はGitHub ActionsでAmazon ECRにイメージをプッシュする例です。(実際には、この後ECSにデプロイするなどのステップが続きます。)

こちらのブログで指摘されているのですが、コンテナ内でビルドを行う場合、工夫がないと毎回ゼロからビルドが始まってしまいます。そのため、Jibを使用してコンテナ化することで、setup-javaやsetup-gradleのキャッシュ機構を活用することができ、ビルド時間の短縮ができそうです。

name: Build and Push to ECR

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  id-token: write

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version-file: .java-version

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Configure AWS credentials with IAM Role
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          aws-region: ap-northeast-1

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build and push with Jib
        run: |
          ./gradlew jib \
            -Djib.to.image=${{ steps.login-ecr.outputs.registry }}/${{ secrets.ECR_REPOSITORY }}:${{ github.sha }} \
            -Djib.to.auth.username=AWS \
            -Djib.to.auth.password=${{ steps.login-ecr.outputs.docker-password }}

まとめ

Jibは、JavaやKotlinプロジェクトのコンテナ化を劇的に簡素化し、高速化します。この記事が誰かの参考になりましたら幸いです。それではまた!

今回ご紹介したサンプルコードは以下のリポジトリにあります。
https://github.com/hori-design/jib-containerize-demo

ispec inc.

Discussion

ログインするとコメントできます