Java application containers with Gradle and Rockcraft

Introduction
In the previous post of this series, I introduced the Rockcraft Maven plugin. I demonstrated how application container images could be easily created as a part of a Java developer’s typical Maven workflow. This post introduces the Gradle Rockcraft plugin.
You are developing, or maintaining, a Gradle-based Spring Boot application. During your development iterations, you want to test the application in a container that is resembles the deployment container. This post demonstrates how you could do this as a part of your development workflow using Gradle.
Setup
I assume you have the Java development environment set up. For this demo, I used a Java 21 on the host, because the generated Ubuntu ROCK has the same version installed.
Ubuntu ROCKs are OCI-compliant container images that can be stored in an OCI-compliant registry like DockerHub
and used by any OCI-compliant tool like Docker. Rockcraft is a command-line tool used to create ROCK images from a YAML-based declarative syntax.
Rockcraft is available as a snap and should be installed as a prerequisite.
snap install rockcraft --classic
If not already present, install docker.
snap install docker --classic
Gradle installation
Spring 3.3 requires Gradle 7.6 and above. Specifically, this demo needs Gradle 8.X. The required version may be installed from the snap store:
# Gradle 8.X is published on the --edge channel only
snap install gradle --classic --edge
gradlew
) that comes with the project.Building application container images
I use this simple Spring Boot application as an example for this demo.
Step 1: Clone the application repository
git clone https://github.com/spring-guides/gs-spring-boot/
cd gs-spring-boot/initial
Step 2: Configure the Gradle rockcraft plugin
Simply add the Gradle Rockcraft plugin to the list of plugins in the build.gradle
file. To keep things simple, we will use the default configuration.
plugins {
id 'org.springframework.boot' version '3.3.0'
id 'java'
id 'io.github.rockcrafters.rockcraft' version '1.1.3' // <<< ADD THIS
}
Step 3: Run the Gradle build
Like the Maven plugin, the Gradle plugin also defines the create-rock
, build-rock
and push-rock
tasks:
1. create-rock
creates the Rockcraft YAML
2. build-rock
depends on create-rock
and builds the rock from the YAML
3. push-rock
depends on build-rock
and pushes the rock as a docker image to the local docker daemon.
To execute all three tasks, it suffices to invoke the push-rock
task:
gradle push-rock -i
build-rock
task might take a couple of minutes to complete, when run for the first time.Step 4: Run the application container
Assuming that the previous step completed successfully, you should now find a new image in your local docker daemon.
$docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-boot 0.0.1-SNAPSHOT c1dd98eb04e5 35 seconds ago 134MB
spring-boot latest c1dd98eb04e5 35 seconds ago 134MB
By default, Ubuntu ROCK images package the Pebble service manager which also acts as the default entrypoint into the image. From a usability point-of-view this only means that the docker run
command to launch the container might appear a little different, if you are a regular docker
user. We use Pebble’s exec
service to launch the Java application:
docker run --network=host spring-boot:latest exec \
/usr/bin/java -jar /jars/spring-boot-0.0.1-SNAPSHOT.jar
Step 5: Iterate
During local development, you could repeat steps 3 and 4 over and over again. Every time a new image would be created and pushed to the local docker daemon.
Here is a screen-cast that captures steps 1 through 5.
What’s next?
Have you noticed the sizes of the container images? Can we reduce them by packaging only what the application needs? I plan to address this requirement in the next post.
Thank you for reading!
Subscribe to my newsletter
Read articles from Pushkar Kulkarni directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
