CLOVER🍀

That was when it all began.

JibでローカルのDockerイメージをベースイメージにする場合は、「docker://」をプレフィックスにつける

これは、なにをしたくて書いたもの?

JibでローカルにしかないDockerイメージをベースイメージにしようとして、少しハマったのでメモしておきます。

通常はどこかのDockerレジストリーに登録すると思うので、ちょっとした確認用途などでしか使わないと思いますが。

結論としては、使用するベースイメージの名前の前にdocker://接頭辞を付けるようにします。

環境

今回の環境はこちら。

$ java --version
openjdk 21.0.6 2025-01-21
OpenJDK Runtime Environment (build 21.0.6+7-Ubuntu-124.04.1)
OpenJDK 64-Bit Server VM (build 21.0.6+7-Ubuntu-124.04.1, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 21.0.6, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-53-generic", arch: "amd64", family: "unix"

Docker。

$ docker version
Client: Docker Engine - Community
 Version:           28.0.0
 API version:       1.48
 Go version:        go1.23.6
 Git commit:        f9ced58
 Built:             Wed Feb 19 22:11:04 2025
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          28.0.0
  API version:      1.48 (minimum version 1.24)
  Go version:       go1.23.6
  Git commit:       af898ab
  Built:            Wed Feb 19 22:11:04 2025
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.25
  GitCommit:        bcc810d6b9066471b0b6fa75f557a15a1cbf31bb
 runc:
  Version:          1.2.4
  GitCommit:        v1.2.4-0-g6c52b3f
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

サンプルアプリケーションを作る

本題に入る前に、サンプルアプリケーションを作成します。この時点でJib Maven Pluginも導入しておきます。

RESTEasyを使って、Jakarta RESTful Web ServicesのSeBootstrapで簡単なサンプルを作成。

    <properties>
        <maven.compiler.release>21</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-core</artifactId>
            <version>6.2.11.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-undertow-cdi</artifactId>
            <version>6.2.11.Final</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>3.4.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>dockerBuild</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <from>
                        <image>eclipse-temurin:21.0.6_7-jdk-noble</image>
                    </from>
                    <to>
                        <image>kazuhira/app</image>
                    </to>
                    <container>
                        <ports>
                            <port>8080</port>
                        </ports>
                    </container>
                </configuration>
            </plugin>
        </plugins>
    </build>

ベースイメージは、Eclipse Temurinにしておきます。

                    <from>
                        <image>eclipse-temurin:21.0.6_7-jdk-noble</image>
                    </from>

またmvn packageでDockerイメージをビルドするようにしています。

                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>dockerBuild</goal>
                        </goals>
                    </execution>
                </executions>

src/main/java/org/littlewings/jib/HelloResource.java

package org.littlewings.jib;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class HelloResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String message() {
        return "Hello World!!";
    }
}

src/main/java/org/littlewings/jib/RestApplication.java

package org.littlewings.jib;

import java.util.Set;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@ApplicationPath("/")
public class RestApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        return Set.of(HelloResource.class);
    }
}

src/main/java/org/littlewings/jib/App.java

package org.littlewings.jib;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import jakarta.ws.rs.SeBootstrap;

public class App {
    public static void main(String... args) throws ExecutionException, InterruptedException {
        SeBootstrap.Configuration configuration =
                SeBootstrap
                        .Configuration
                        .builder()
                        .host("0.0.0.0")
                        .port(8080)
                        .build();

        SeBootstrap
                .start(new RestApplication(), configuration)
                .toCompletableFuture()
                .get();

        while (true) {
            try {
                TimeUnit.SECONDS.sleep(1L);
            } catch (InterruptedException e) {
                // ignore
            }
        }
    }
}

Dockerイメージを作成。

$ mvn package

できました。

$ docker image ls
REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
kazuhira/app      latest    22e4fb026093   55 years ago   457MB

起動。

$ docker container run -it --rm --name app -p 8080:8080 kazuhira/app:latest

動作確認。

$ curl localhost:8080/hello
Hello World!!

OKですね。

ベースイメージをローカルにしかないものにしてみる

先ほどは、Eclipse Temurinをベースイメージにしました。

                    <from>
                        <image>eclipse-temurin:21.0.6_7-jdk-noble</image>
                    </from>

ここを、ローカルにしかないイメージに差し替えてみます。

特に内容には凝らないので、単に名前を変えるくらいのものにしてみます。

Dockerfile

FROM eclipse-temurin:21.0.6_7-jdk-noble

ビルド。

$ docker image build -t kazuhira/my-temurin:21.0.6_7-jdk-noble .

では、このイメージを使うようにJib Maven Pluginの設定を変更してみます。

                    <from>
                        <!--
                        <image>eclipse-temurin:21.0.6_7-jdk-noble</image>
                        -->
                        <image>kazuhira/my-temurin:21.0.6_7-jdk-noble</image>
                    </from>

パッケージング。

$ mvn package

すると、DockerHubを見に行ってしまうのでビルドに失敗します。

[ERROR] Failed to execute goal com.google.cloud.tools:jib-maven-plugin:3.4.4:dockerBuild (default) on project local-base-image: Build to Docker daemon failed, perhaps you should make sure your credentials for 'registry-1.docker.io/kazuhira/my-temurin' are set up correctly. See https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#what-should-i-do-when-the-registry-responds-with-unauthorized for help: Unauthorized for registry-1.docker.io/kazuhira/my-temurin: 401 Unauthorized
[ERROR] GET https://registry-1.docker.io/v2/kazuhira/my-temurin/manifests/21.0.6_7-jdk-noble
[ERROR] {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"kazuhira/my-temurin","Action":"pull"}]}]}
[ERROR] -> [Help 1]

よく見ると以下のヘルプが案内されているのですが、これはレジストリーの認証がうまくいかない場合のトラブルシュートです。

Frequently Asked Questions (FAQ) / What should I do when the registry responds with UNAUTHORIZED?

今回はローカルにしかないイメージを使いたいので、見るべきなのはこちらですね。

Jib - Containerize your Maven project / Extended Usage / Example / Setting the Base Image

こちらを見ると、docker://接頭辞を付けてDockerデーモンからイメージを取得するようにするのが正解でしょう。

Retrieves the base image from the Docker daemon.

というわけで、こう変更。

                    <from>
                        <image>docker://kazuhira/my-temurin:21.0.6_7-jdk-noble</image>
                    </from>

再度Dockerイメージをビルド。

$ mvn package

今度はうまくビルドできました。

[INFO] --- jib:3.4.4:dockerBuild (default) @ local-base-image ---
[INFO]
[INFO] Containerizing application to Docker daemon as kazuhira/app...
[WARNING] Base image 'kazuhira/my-temurin:21.0.6_7-jdk-noble' does not use a specific image digest - build may not be reproducible
[INFO]
[INFO] Container entrypoint set to [java, -cp, @/app/jib-classpath-file, org.littlewings.jib.App]
[INFO]
[INFO] Built image to Docker daemon as kazuhira/app
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  12.599 s
[INFO] Finished at: 2025-02-22T18:32:12+09:00
[INFO] ------------------------------------------------------------------------

おわりに

JibでローカルのDockerイメージをベースイメージにする場合に、どうしたらいいのか調べてみました。

意外とハマりそうな気がするので、使う機会は少ないでしょうけれど覚えておきましょう。