By default, always publish an updated latest tag to the configured docker registry when using a custom docker image name using the Spring Boot Maven Plugin in this fashion: https://docs.spring.io/spring-boot/maven-plugin/build-image.html#build-image.examples.custom-image-name

Currently, the plugin will only publish the supplied image tag for the provided custom image name, which includes the tag. I can't think of a reason why we wouldn't want publishing an updated latest tag to be the default behavior. If we want to make it optional, we could even provide a new flag such as image.publishLatest that would enable this behavior if a custom image name is provided.

Comment From: scottfrederick

Thanks for the suggestion.

I can't think of a reason why we wouldn't want publishing an updated latest tag to be the default behavior.

I don't think that all users would agree with this. If images are being built and published from a CI pipeline, you may not want latest to be updated with every build, but instead you might want to explicitly decide when to promote a build to latest. Changing the default behavior like this could be quite a surprise for many users.

If we want to make it optional, we could even provide a new flag such as image.publishLatest

With the current functionality, if you wanted to always publish a latest along with the versioned tag, you would do something like this:

<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <image>
            <name>example.com/library/${project.artifactId}:${project.version}</name>
            <tags>
              <tag>example.com/library/${project.artifactId}:latest</tag>
            <tags>
            <publish>true</publish>
          </image>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

A new option like image.publishLatest would eliminate the need for the <tags></tags> section, but in a much less flexible way. I don't think implementing a new, less flexible, option to replace something that can already be done has value. I also would not want to combine the behavior of the <publish>true</publish> option and a tagging option into one new option.

Are you doing something different from this <tags></tags> example now, or do you find this configuration too verbose?

Comment From: dja557

@scottfrederick - I guess my question would be, what is the recommended approach to do this via the command line in CI when we need to set a custom tag name and also publish an updated latest tag while also having to pass credentials to authenticate to the docker registry?

Comment From: scottfrederick

We typically don't expose the more complex and/or nested option types as command-line parameters for Maven plugin goals (including env, buildpacks, bindings, and tags for spring-boot:build-image). I think we added support for docker.publishRegistry.username and docker.publishRegistry.password as command-line options because it is likely that these contain sensitive information that you would not want to hard-code in pom.xml.

If you need to set tags or other options conditionally, the recommended approach is to use Maven profiles and activate the appropriate profile from the command line using mvn -P <profileName>.

Comment From: dja557

@scottfrederick - Thanks for the feedback. I'd say that since Spring Boot is built for the enterprise and large-scale business use-cases that typically have private docker registries, I'd recommend adding the image.tags option as a command-line parameter so that it can be set via CI at build/publish time. Also, it would be great to be able to set the docker.publishRegistry.* parameters without having to manually pipe them into the pom.xml as mentioned here since we have to regularly pull these secrets from an external secrets store or GitHub Actions.

I was able to workaround these constraints by doing the following. Hopefully this helps someone if they're encountering the same issue.

pom.xml

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
    <docker>
        <publishRegistry>
            <username>${docker.publishRegistry.username}</username>
            <password>${docker.publishRegistry.password}</password>
        </publishRegistry>
    </docker>
    <image>
        <tags>
            <tag>docker.artifactory.xyz.com/my_image:latest</tag>
        </tags>
    </image>
    </configuration>
</plugin>

CLI Command

mvn spring-boot:build-image \
     -Dmaven.test.skip=true \
     -Ddocker.publishRegistry.username=username \
     -Ddocker.publishRegistry.password=password \
     -Dspring-boot.build-image.publish=true \
     -Dspring-boot.build-image.imageName=docker.artifactory.xyz.com/my_image:generated_image_tag

Comment From: scottfrederick

@dja557 The technique that you've shown here is very similar to what we recommend in our documentation for overriding Maven configuration properties on the command line. In the case of credentials like these, I think it is more likely that the values will be environment variables populated by a CI system from a secrets store rather than command-line parameters.

We appreciate the feedback and suggestions, but I don't think we want to do anything more here.