Java application containers with Maven and Rockcraft

Introduction
You are developing a Maven-based Spring Boot application. This Java application will be eventually production-deployed, as a micro-service, in a container. Well, let us assume an Ubuntu-based chiseled container! During your development iterations you want to test the application in a container that is the same as the production container. Consequently, your development iterations have an additional step following the maven build - creating the container image. Can we simply add this step to the Maven workflow?
This Rockcraft Build Plugins can let you create application container images as a Maven build artifact. In this post, I demonstrate the use of the Maven Rockcraft plugin.
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
snap connect
commands in this section of the docker-snap README.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: Add the Maven Rockcraft plugin to the pom.xml
Add the following XML to the pom.xml file as a build plugin:
<plugin>
<groupId>io.github.rockcrafters</groupId>
<artifactId>rockcraft-maven-plugin</artifactId>
<version>1.1.2</version>
<executions>
<execution>
<configuration>
<createService>false</createService>
</configuration>
<goals>
<goal>create-rock</goal>
<goal>build-rock</goal>
<goal>push-rock</goal>
</goals>
</execution>
</executions>
</plugin>
Step 3: Run mvn install
In the XML above, we see three new goals added by the rockcraft-maven-plugin
:
1. The create-rock
goal generates the rockcraft.yaml
for this application in the target
directory
2. The build-rock
goal builds an OCI-compliant Ubuntu ROCK image, again in the target
directory
3. The push-rock
goal copies this image to the local Docker daemon
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-initial 0.0.1-SNAPSHOT e49f7a343c87 About a minute ago 145MB
spring-boot-initial latest e49f7a343c87 About a minute ago 145MB
...
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-initial:latest exec \
/usr/bin/java -jar /jars/spring-boot-initial-0.0.1-SNAPSHOT.jar
<artifact-id>-<version>.jar
. In the container image, this JAR is placed under the /jars
directory.The last command should start up a Spring Boot application listening at port 8080. You may now access http://localhost:8080
from a browser to see a Greetings for Spring Boot!
message.
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.
Thanks for reading along! In the next article in this series, I plan to write about the Gradle plugin for creating container images.
Subscribe to my newsletter
Read articles from Pushkar Kulkarni directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
