Yesterday (January 23, 2020), Spring Boot 2.3.0 M1 was released. One of the highlights in this milestone is the support for building OCI images using Cloud Native Buildpacks.

Build a (Docker) image for your Spring Boot application in minutes! You can find the complete example project used in this blog post at my Github account.

Update: Spring Boot 2.3 has been released Friday, May 15th.

So please use the released version instead of the Milestone version!

What are Cloud Native Buildpacks?

From https://buildpacks.io/:

The Cloud Native Buildpacks project was initiated by Pivotal and Heroku in January 2018 and joined the Cloud Native Sandbox in October 2018. The project aims to unify the buildpack ecosystems with a platform-to-buildpack contract that is well-defined and that incorporates learnings from maintaining production-grade buildpacks for years at both Pivotal and Heroku.

Buildpacks provide a higher-level abstraction for building applications compared to Dockerfiles. The job of a buildpack is to detect and gather everything your application needs to build and run.

Long story short, a buildpack will transform your source code into a runnable application image!

Spring Boot 2.3.0 Milestone 1 introduces the support for building Docker images using Cloud Native Buildpacks has been added to the:

I use Maven in this blog post.

Prerequisites

Make sure you have Docker installed. If not, install Docker.

Optionally install Docker Compose as well.

Verify Docker:

docker -v

Docker version 19.03.5, build 633a0ea838

And optionally Docker Compose:

docker-compose -v

docker-compose version 1.25.3, build d4d1b42b

Create a new project

Every new Spring Boot adventure starts at start.spring.io!

Select Maven Project and next Spring Boot version 2.3.0 (or later) and include dependencies Spring Web and Spring Boot Actuator and generate the project.

Kickstart your new Spring Boot 2.3.0 project

Add a simple Spring MVC Rest Controller

This blog is not about fancy code. But at least I would like to show something in the browser to verify the container (running my Spring Boot application) started correctly.

Build the Image for the Spring Boot Application

Now package the application source code into an OCI image using the Spring Boot Maven plugin and buildpacks:

./mvnw spring-boot:build-image

When the build succeeds, you should be able to see the image using Docker:

Run the application using Docker

Now it’s time to start a container via Docker. A container is a running instance of an image. You can compare a container to an image like how an object is an instance of a class.

docker run -d -p 8080:8080 --name springbootcontainer cloud-native-buildpacks-example:0.0.1-SNAPSHOT

Check whether or not the container is running:

Now hit localhost:8080 in your favorite browser to see the greeting from the simple Spring MVC Rest controller. Excellent, the application is up and running in the container!

Also take a look at the Spring Boot info actuator endpoint: http://localhost:8080/actuator/info

You can verify the Spring Boot application is running on Adopt Open JDK version 11.0.5. The show the Java and application details customize the Spring Boot info actuator in your application.yml configuration file.

To stop the container run:

docker stop springbootcontainer

Run the application using Docker Compose

Alternatively, you can also run the image using Docker compose.

Check out the docker-compose.yml at the root of the project.

Start:

docker-compose up -d

Show running containers (started using Docker Compose):

docker-compose ps

Stop:

docker-compose down

Customizing the name of your image

By default, the name of the image is based on the artifactId and the version of your Maven project:

docker.io/library/${project.artifactId}:{project.version}

In a real-life project, you would like to push the OCI image to a specific (Docker) image registry. In my case I would like to push the OCI image to my public repo on Dockerhub as:

docker.io/jtim/cloud-native-buildpacks-example:latest

To be able to push the image I need to configure the name of the image:

Now I can push the image to Dockerhub:

docker push docker.io/jtim/cloud-native-buildpacks-example

Customize the Cloud Native builder

By default, the Cloud Native Buildpacks builder used to build your image is cloudfoundry/cnb:0.0.43-bionic.

The base image is determined by the builder. You can choose a different one by configuring a different builder:

During this first look at Cloud Native Buildpack support, I was not able to find a different builder that was able to build my Spring Boot application. If you find one please let me know.

Update: Since Spring Boot 2.3.0.RC1 Paketo Java buildpack is used by default to create images.

Wrap up

This blog post was just a first look into the Spring Boot 2.3.0 milestone one and Buildpacks. I showed you how easy it is to turn your codebase into an OCI image that can run on Docker.

Continue reading and learning:

Buildpacks.io

Spring Boot 2.3.0 M1 Maven plugin documentation

Spring Boot 2.3.0 M1 Gradle plugin documentation

Spring Boot 2.3 Milestone 1 release notes

For in-depth information about OCI and specification see:

The current version (at the time of writing this blog) of Spring Boot is 2.2.4. To learn more about the features of Spring Boot 2.2, read my blog post:

What’s new in Spring Boot 2.2?