すべてのプロダクト
Search
ドキュメントセンター

Container Registry:Java プロジェクトのコンテナ化におけるベストプラクティス

最終更新日:Aug 29, 2026

Dockerfile を使用してソースコードをコンテナイメージにビルドし、そのイメージを配布・デプロイします。Java プロジェクトは、Golang や Python プロジェクトよりもコンテナ化が難しく、ビルドが遅くなる傾向があります。多くの企業では、Maven などの自己管理型の依存関係リポジトリに依存しており、開発者は Dockerfile のキャッシュメカニズムに不慣れなことがよくあります。このトピックでは、クラウド上の自己管理型 GitLab コードリポジトリと自己管理型 Maven リポジトリという典型的なシナリオから始めます。Dockerfile を使用して Java プロジェクトをビルドする方法と、各ビルドを高速化する方法を説明します。また、Container Registry Enterprise Edition (ACR EE) のビルドサービスを使用してイメージビルドを自動化する方法も紹介します。

前提条件

  • GitLab コードリポジトリを作成済みであること。

  • Maven リポジトリを作成済みであること。

  • Container Registry Enterprise Edition インスタンスを作成済みであること。詳細については、「Enterprise Edition インスタンスの作成」をご参照ください。

プロジェクト概要

このトピックでは、相互に依存する 2 つの Java プロジェクトを使用したビルドプロセスを例示します。プロジェクトは以下の通りです:

  • Provider:呼び出し可能なサービスを提供します。

    • Core モジュール:パブリックインターフェイスを提供します。

    • Service モジュール:サービス実装モジュールです。

  • Consumer:Provider サービスを呼び出します。

    • Service モジュール:Provider プロジェクトの Core モジュールに依存します。次のコードは一例です:

      .
      ├── consumer
      │ ├── Dockerfile
      │ ├── consumer.iml
      │ ├── pom.xml
      │ └── service
      │     ├── pom.xml
      │     ├── src
      │     └── target
      └── provider
          ├── Dockerfile
          ├── core
          │ ├── pom.xml
          │ ├── src
          │ └── target
          ├── pom.xml
          ├── provider.iml
          └── service
              ├── pom.xml
              ├── src
              └── target

ビルド成果物:

  • Provider プロジェクトからビルドされたプロデューサーアプリケーションイメージ。

  • Consumer プロジェクトからビルドされたコンシューマーアプリケーションイメージ。

手順 1: 共有依存関係のデプロイ

Consumer プロジェクトをビルドする前に、それが依存する Provider プロジェクトの成果物を自己管理型 Maven リポジトリにデプロイする必要があります。Provider プロジェクトのディレクトリで次のコマンドを実行します:

mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests

手順 2: カスタム Maven ベースイメージの作成

コンテナ化されたビルド環境で自己管理型 Maven リポジトリにアクセスするには、Maven リポジトリの設定をベースイメージに追加します。公式の Maven イメージを基に、企業向けのカスタムのパブリック Maven ベースイメージを作成します。これにより、アプリケーションプロジェクトはこのベースイメージを参照して Maven リポジトリにアクセスできるようになります。

  1. 次の内容を Dockerfile として保存し、Maven リポジトリの settings.xml ファイルと同じディレクトリに配置します。

    FROM maven:3.8-openjdk-8 # プロジェクトに適合する Maven イメージを使用します。この例では Maven 3.8 を使用します。
    ADD settings.xml /root/.m2/ # 自己管理型 Maven リポジトリの設定を指定されたパスに追加します。
  2. 次のコマンドを実行してイメージをビルドし、リモートのイメージリポジトリにプッシュします。

    ls
    Dockerfile   settings.xml
    docker build -t demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 -f Dockerfile .
    Sending build context to Docker daemon   7.68kB
    Step 1/2 : FROM maven:3.8-openjdk-8
     ---> a3f42bfde036
    Step 2/2 : ADD settings.xml /root/.m2/
     ---> db0d5a5192e3
    Successfully built db0d5a5192e3
    Successfully tagged demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8
    docker push demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8

手順 3: Consumer アプリケーションイメージのビルド (Provider プロジェクトは対象外)

次のコマンドを実行します。(ビルドプロセス中に必要なすべてのベースイメージを Alibaba Cloud イメージリポジトリにプッシュしてください。)

FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder
# pom.xml とソースコードを追加します
ADD ./pom.xml pom.xml
ADD ./service service/
# JAR をパッケージ化します
RUN mvn clean package
# 第 2 段階:最小ランタイム環境
From demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine
# 第 1 段階から JAR をコピーします
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]

手順 4: ビルド速度の最適化

「手順 3: Consumer アプリケーションイメージのビルド (Provider プロジェクトは対象外)」でイメージをビルドしました。しかし、コードを修正して再ビルドすると、キャッシュを使用せずに JAR パッケージを再度ダウンロードするため、ビルドプロセスが遅いことに気づくでしょう。Docker は、レイヤーのコンテンツが変更されると、そのレイヤーのキャッシュを無効にします。ソースコードを修正すると、ADD 命令内のファイルのハッシュが変更されます。この変更により、RUN 命令が強制的に再実行され、前回のビルドのキャッシュが無視されます。詳細については、「Dockerfile のベストプラクティス」をご参照ください。

ビルド速度を最適化するために、Maven の依存関係をキャッシュして再利用します:

  1. まず、プロジェクトの pom.xml ファイルをコンテナにコピーして、依存関係をダウンロードします。pom.xml ファイルが変更されない限り、後続のビルドではキャッシュを使用できます。

  2. プロジェクトのソースコードをコピーしてコンパイルします。

以下は改良版の Dockerfile です。最初のビルドには 43 秒かかります。ソースコードのみを変更した場合、後続のビルドは 7 秒で完了します。

FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder
# 依存関係を解決し、ソースコードの変更時に再ダウンロードしないようにします
ADD ./pom.xml pom.xml
ADD ./service/pom.xml service/pom.xml
RUN mvn dependency:go-offline
ADD ./service service/
# JAR をパッケージ化します
RUN mvn clean package
# 第 2 段階:最小ランタイム環境
From demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine
# 第 1 段階から JAR をコピーします
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]

手順 5: Container Registry Enterprise Edition によるビルドプロセスの自動化

ACR EE はエンタープライズレベルのビルドサービスを提供し、エンタープライズのお客様に推奨されます。 詳細については、「エンタープライズ版インスタンスを使用してイメージをビルドするエンタープライズ版インスタンスを使用してイメージをビルドする」をご参照ください。

以下のセクションでは、いくつかのベストプラクティスを概説します。

  • VPC ビルドモードの使用

    クラウド上のセルフマネージド GitLab インスタンスでは、セキュアな VPC ビルドモードを使用してイメージをビルドします。これにより、サービスがパブリックインターネットに公開されるのを防ぎます。詳細については、「セキュアな VPC モードでコンテナイメージをビルドするセキュアな VPC モードでコンテナイメージをビルドする」をご参照ください。

  • イミュータブルイメージバージョン機能の使用

    リポジトリのイミュータブルイメージバージョン機能を有効にすると、オンラインバージョンが上書きされるのを防ぐことができます。[Create Image Repository] ページの [Repository Information] ステップで、[Image Version] の [Immutable] チェックボックスをオンにします。チェックボックスをオンにすると、リポジトリ内の latest を除くどのイメージバージョンも上書きできなくなります。これにより、コンテナイメージのバージョンの一貫性が保たれます。

  • コミット ID に基づくビルドルールの作成

    各ビルドで 2 つのイメージバージョンが生成されます。1 つのバージョンはコードのコミット ID を使用するため、イメージバージョンをコードバージョンに対応付けることができます。もう 1 つのバージョンは latest を使用して最新バージョンを示します。[Modify Building Rule] ダイアログボックスの [Image Version] ステップで、[Commit ID] と [latest] のイメージバージョンが設定されています。

    コードをコミットしてビルドをトリガーします。次の例は、2 つのコードコミットによって自動的にトリガーされた 2 つのビルドを示しています。各ビルドで 2 つのイメージが生成され、2 回目のビルドはキャッシュが効くため高速になります。ビルド設定ページでは、[コード変更時のイメージ自動ビルド] スイッチが有効になっています。ビルドルールの設定では、ブランチが branches:master に、ビルドコンテキストディレクトリが / に、Dockerfile 名が Dockerfile に設定されています。イメージバージョンには、コミット ID バージョンと最新バージョンに対応する [Configuration 1] と [Configuration 2] の 2 つのタグが含まれています。ビルドログには、両方のビルドが正常に完了し、それぞれ 106 秒と 85 秒かかったことが示されています。