Currently, the way spring-boot:build-image is designed, makes it difficult to separate image building and image pushing in 2 different Maven lifecycle phases.

The idea would be to separate both actions in different goals, binding push-image to the deploy phase.

If this sounds interesting, I can contribute the pull request.

Comment From: scottfrederick

Thanks for the suggestion. The primary focus of the spring-boot:build-image goal in the Spring Boot Maven plugin is to integrate with the Cloud Native Buildpacks workflow to generate Docker images from a Spring Boot application using buildpacks. The publishing capability was added for parity with the pack CLI, which supports publishing the built image with pack build --publish.

We are hesitant to expand the Spring Boot plugin beyond CNB integration with a broader Docker-related feature set, as there are other Maven plugins that provide Docker integration. For example, the fabric8 Docker plugin has several fine-grained goals for working with Docker images beyond building an image. Adding configuration like the example below along with the Spring Boot plugin configuration in pom.xml would enable a workflow like mvn spring-boot:build-image docker:push, and allow those goals to be bound to different lifecycle phases.

    <plugins>
      ...
      <plugin>
        <groupId>io.fabric8</groupId>
        <artifactId>docker-maven-plugin</artifactId>
        <version>0.35.0</version>
        <configuration>
          <images>
            <image>
              <name>${project.artifactId}:${project.version}</name>
            </image>
         </images>
        </configuration>
      </plugin>
    </plugins>

Would a combination of Maven plugins like this meet your needs?

Comment From: alvarosanchez

Thanks for the feedback. I see and agree with your point of view. However, please note that I'm not suggesting adding new Docker-related functionality to the plugin, but rather expose existing functionality in its own goal.

I know I could use other plugins, or even the Docker CLI, but the push logic offered by this plugin just works. No need to add more dependencies. Moreover, The Fabric8 Maven plugin is deprecated and superseded by JKube. And using JKube just for pushing a Docker image seems overkilling.

Finally, regarding the parity with the pack CLI, I understand the idea behind it. But be aware that their workflow doesn't work well when moved into a Maven plugin. Doing mvn package -Dspring-boot.build-image.publish=true has the side effect of potentially pushing a Docker image that can have later test failures during the verify phase. It's unpractical to use it as it is now.

So long story short, I still think the cost/benefit of this suggestion makes it worthy. While I understand your concerns from a framework maintainer point of view, I also think that making existing features actually useable, and improving the ergonomics and user experience, is important.

Comment From: scottfrederick

please note that I'm not suggesting adding new Docker-related functionality to the plugin, but rather expose existing functionality in its own goal.

While this wouldn't introduce a new capability to the plugin, it would open up the plugin to new usage patterns. Currently the plugin only has the ability to push the image built by spring-boot:build-image. Adding a new goal like spring-boot:push-image would make it possible for a user to use that goal to push any images by setting the image name in the build configuration. Our concern is that projects could use this new goal in unintended ways, and set the expectation that we are open to extending the plugin beyond its focus on CNB integration.

But be aware that [the pack] workflow doesn't work well when moved into a Maven plugin. Doing mvn package -Dspring-boot.build-image.publish=true has the side effect of potentially pushing a Docker image that can have later test failures during the verify phase.

This came up in our team discussion a few days ago, and that viewpoint is understood. Both pack and the Spring Boot build plugins work well for a developer inner-loop workflow, but are not best suited for a CI/CD type workflow. Other tools with CNB integration like kpack and Tekton provide more capabilities for building larger-scale build/test/publish/deploy pipelines.

We can keep this under consideration while we think about where the Spring Boot build plugins fit into the various possible workflows. At this point in the release cycle, after the 2.5.0 release candidate has been published, an enhancement like this wouldn't be considered until a 2.6.0 release at the earliest.

Comment From: alvarosanchez

OK, fair enough. I will keep an eye on this issue to see if this decision is revisited in the future.

Thanks!

Comment From: recena

One of the best approaches in the CI/CD scope is to design everything reproducible locally. I don't know we would have to use different solutions for CI/CD and developer inner-loop workflow.

👍 For the @alvarosanchez proposal.

Comment From: philwebb

We discussed this issue again today on our call and decided that we don't want to introduce a new goal at this time. Although there are a few good arguments for the idea, we're concerned about both the maintenance cost and the impression that a new goal will give. We really only intended the build-image goal to be a quick way to get started with buildpacks. It wasn't our intention for the goal to be used for full CI/CD orchestration. We'd prefer to keep things aligned with pack for now and suggest that people use kpack and CI pipelines for more complex setups.

Thanks for the suggestion though.