YMNNALFT: Easy Docker Image Creation with the Spring Boot Maven Plugin and Buildpacks

Engineering | Josh Long | January 04, 2021 | ...

Welcome to another installment of You May Not Need Another Library For That (#YMNNALFT)! I've spent a lot of time since 2016 illuminating (or trying to, anyway!) some of the more enormous opportunities in the Spring ecosystem in my Spring Tips videos. Today, however, I come to you in a different spirit, wanting to focus on the little, sometimes hidden, gems that do fantastic things and that might spare you an additional third-party dependency and its implied complexity.

Have you tried out Paketo? It's neat-o! It alleviates one of the biggest pains of cloudy software these days:Dockerfiles.

As an aside: the biggest pain point is, of course, YAML. YAML is why people leave IT! YAML: when you want the indentation-sensitive treachery of Python, with the nonexistent design-time validation of Python and none of the benefits of Python. YAML: because life is, clearly, not hard enough. 9/10 dentists agree: YAML causes production rot!

"Indeed it has been said that YAML is the best form of configuration except for all those other forms that have been tried from time to time." - Not Winston Churchill

Aaaanyway, YAML is a whole, other, "Oprah," and we just don't have a ton of time to get into it, so let's move on: we want to simplify the creation of Dockerfiles. Dockerfiles are tedious and they require us to re-specify the complete environment required to run our applications in production. It's possible to get something working in a fairly minimal number of lines, but as I learned while avoiding the COVID-19 virus, "minimal" is not "none!" And besides, something working does not a production environment make. We can do better.

Paketo is a Cloud Foundry foundation project based on the buildpacks project from CNCF (which stands for "Code Never Comes Finished," or maybe it was "Common Network Code Foundation," or was it "Cloud Native Computing Foundation"?). From the website: "buildpacks transform your application source code to images that can run on any cloud. Paketo Buildpacks provide language runtime support for applications. They leverage the Cloud Native Buildpacks framework to make image builds easy, performant, and secure." Basically: application in; container out. See? Neat!

Buildpacks come from the Heroku and Cloud Foundry Platform-as-a-service offerings. You give the buildpack an application artifact (like, say, a Java .jar), and the buildpack gives you back your application in a container. More specifically, it'll create a sensible filesystem containing your application artifact and everything needed to run that application artifact. So, given a .jar, it might create a filesystem with a JVM configured with reasonable memory bounds and any required Java agents configured. All of that is what eventually gets turned into a container. You'd be shocked what you can get containerized with virtually no configuration at all! Buildpacks work because, no matter how much we may protest, most applications aren't special. A .jar is a .jar for everybody, and a Node.js/NPM project builds the same for everybody. Buildpacks support several different languages and runtime (way too many to name). You can use the Paketo CLI to make short work of containerizing various applications, like this: pack build ..

Or, anyway, that's what you would do if you were not using Spring Boot 2.3 or later. But, you are, _ aren't you_? Buildpack support is now in the Spring Boot build plugins themselves.

If you were using Maven, you could type the following incantation:

./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=bootiful/demo

If you were using Gradle, you could type the following incantation:

./gradlew bootBuildImage --imageName=bootiful/demo

Stand back for a minute while it does all the work. It'll dump out the Docker image at the end of its work. You can then docker tag and then docker push that image to your container registry of choice (VMware Harbor, Google Container Registry, JFrog Container Registry, DockerHub, etc.).

Do you want to take that to production? That's pretty trivial, too! Here's the right incantation for Kubernetes, assuming your image is on Google Container Registry, has an artifact ID of demo. The version specified in pom.xml becomes a tag for the version of the container, too.

kubectl create deployment demo --image=gcr.io/bootiful/demo

Hopefully, this is enough to get you to production without so much as even having to configure something like Jib or the Spotify Maven plugin or crafting a long, byzantine shell script to do the docker build itself. Now, don't get me wrong. You might still need to create your own `Dockerfile's for whatever reason, as you might have something to say about the ordering or contents of particular layers, and if so, then Spring Boot has your back here, too.

Alright, that's more than enough to get going. Go to the Spring Initializr (my second favorite place on the internet, after production) and generate a new project and take your containerized application to the platform of your choice.

Did you like this gem at a glance approach? Did you learn anything? As always, I'm keen on hearing from you, so please sound off on Twitter (@starbuxman) ! I'll be back with another installment of YMNNALFT later this week, so be sure not to miss that. I've got installments on, among other things, Easy RPC, The Garden of *Utils objects, Dimensional Metrics with Micrometer, and many, many more topics.

Get the Spring newsletter

Thank you!

Get ahead

VMware offers training and certification to turbo-charge your progress.

Learn more

Get support

Spring Runtime offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription.

Learn more

Upcoming events

Check out all the upcoming events in the Spring community.

View all