spring-bootdockermavenpaketo

Build Spring Boot Docker image with maven: specify JRE Image


We use a private nexus repository to store docker images. There we host our JVM of choice, which we specify in our Dockerfile:

FROM docker-nexus.mycompany.tools/eclipse-temurin:17-jdk-alpine

I try to change our approach to use maven spring-boot:build-image goal instead of writting dockerfiles.

I achived all of the requirements, except one: convincing spring-boot plugn / paketo to download the JVM Docker image (FROM instruction) from a different location.

The most important part here is downloading from our private registry (docker-nexus.mycompany.tools). The specific JVM version is negotiable.

I tried to configure the buildRegistry and publishRegistry (not sure if any of them are relevant to image downloading) to point to our registry.

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <docker>
            <builderRegistry>
                <url>docker-nexus.mycompany.tools</url>
                ... username pass ...
            </builderRegistry>
            <publishRegistry>
                <url>docker-nexus.mycompany.tools</url>
                ... username pass ...
            </publishRegistry>
        </docker>

but the image is still trying to get downloaded by https://github.com (which causes our firewall to block the process):

[INFO]     [creator]       BellSoft Liberica JRE 17.0.12: Contributing to layer
[INFO]     [creator]         Downloading from https://github.com/bell-sw/Liberica/releases/download/17.0.12+10/bellsoft-jre17.0.12+10-linux-amd64.tar.gz

I see here that one can configure different JVMs by choosing a different "buildpack", but of course, no buildpack on this list will look at our private nexus.

Is it possible to get the JVM image being fetched from our private registry, or we have to revert to using Dockerfiles?


Solution

  • There are two ways you can accomplish this.

    1. Use a dependency mirror. This allows you to point buildpacks to a different location for all of the dependencies that they download.

    2. Use a dependency mapping. This allows you to change individual dependencies to be downloaded from a different location.

    Which you use just depends on your needs, but it sounds like you probably want the first option, to point everything to your dependency server.

    To do that, you would set BP_DEPENDENCY_MIRROR in the <env> block of the <configuration> for the Spring Boot Build Tools plugin.

    <env>
      <BP_DEPENDENCY_MIRROR>https://mirror.example.org</BP_DEPENDENCY_MIRROR>
      ...
    </env>
    

    Let’s assume, we have a dependency with the original URI of https://github.com/bell-sw/Liberica/releases/download/11.0.8+10/bellsoft-jre11.0.8+10-linux-amd64.tar.gz. This setting would download the dependency from https://mirror.example.org/bell-sw/Liberica/releases/download/11.0.8+10/bellsoft-jre11.0.8+10-linux-amd64.tar.gz.

    Adjust as is needed for your servers. There are more options available, see the link above.


    Ok, now that you have the buildpack pointed to your mirror, you need to populate the mirror with binaries. There is not presently a tool to do this automatically, but you can do it manually without too much fuss.

    Each buildpack that you use currently includes a complete list of all the downloads that it might need. It's listed in the [metadata] block of the buildpack.toml file.

    For example with Paketo Buildpack for Bellsoft Liberica.

    What you need to do is go through the list and download any of the binaries that your applications will need. Then move them into your mirror.

    From the output you included above, the buildpack is trying to download JRE 17.0.2, so we can fetch that from this URL, which I obtained from buildpack.toml. Then we need to load it into the mirror so that it's reachable at the same path, i.e. https://my-mirror.example.com/bell-sw/Liberica/releases/download/17.0.12+10/bellsoft-jre17.0.12+10-linux-amd64.tar.gz.

    Repeat for any other binaries you need. It's not necessary to do them all, you could opt to only fetch the ones you actually need, but it won't hurt anything to copy them all either.

    Alternative option: You can run the buildpack, and see what URLs it's fetching (it will print them all), and use that to drive the list of what you fetch. This will be painful though as the buildpack fails when a download fails, unless you can do this somewhere that has access to the Internet.