What's New In IT Edge?
 

Spring Boot use Jib to Docker images

Take a look at how this tutorial makes it easier for Java developers to deploy Spring Boot 2 applications to Docker images using Jib.

Discover the future of enterprise automation in the hybrid multi-cloud era. Create the connected, nimble and flexible application environment you need. Download the 451 Research brief to learn how.

Presented by Red Hat

1. Introduction

Ever since I published Microservices using Spring Boot, Jersey, Swagger and Docker, I had entertained the idea of making Package the service into a Docker image section its own blog post.

Back then I used Spotify’s docker-maven-plugin, which required connecting to a Docker host. Also felt it would have been almost identical to the section mentioned.

It was nice to learn Google released an open source tool named Jib aimed at easing containerizing Java applications. No need for a Dockerfile, no need for a Docker daemon, and actually no need for container expertise.

Although you could use Jib to build to a Docker daemon, this post focuses on building a Docker image for Spring Boot applications without requiring a Docker host.

2. Java 7 or 8.2. Requirements

  • Maven 3.2+.

3. Create a Spring Boot 2 Application

Let’s create a Spring Boot 2 application to be shipped in a Docker image:

1

curl "https://start.spring.io/starter.tgz"

2

 -d name="springboot2-docker-demo"

3

 -d description="Simplifying Docker images for Spring Boot 2 apps"

4

 -d bootVersion=2.0.3.RELEASE

5

 -d dependencies=actuator,web

6

 -d language=java

7

 -d type=maven-project

8

 -d baseDir=springboot2-docker-demo

9

 -d groupId=com.asimio.demo

10

 -d artifactId=springboot2-docker-demo

11

 -d version=0-SNAPSHOT

12

 | tar -xzvf -

Let’s configure jib-maven-plugin Maven plugin in pom.xml:

1

...

2

<build>

3

  <plugins>

4

...

5

    <plugin>

6

      <groupId>com.google.cloud.tools</groupId>

7

      <artifactId>jib-maven-plugin</artifactId>

8

      <version>0.9.7</version>

9

      <configuration>

10

        <from>

11

          <image>openjdk:8u171-alpine</image>

12

<!--          <credHelper></credHelper> -->

13

        </from>

14

        <to>

15

          <image>asimio/${project.artifactId}:${project.version}</image>

16

<!--          <credHelper></credHelper> -->

17

        </to>

18

        <container>

19

          <jvmFlags>

20

            <jvmFlag>-Xms512m</jvmFlag>

21

            <jvmFlag>-Xmx512m</jvmFlag>

22

          </jvmFlags>

23

        </container>

24

      </configuration>

25

  </plugin>

26

...

The next section covers what these elements mean.

4. jib-maven-plugin Configuration Explained

configuration:

Element Type Default value Description
from from See from Configures which and how to access the base image
to to See to Configures the resulting image including the application
container container See container Configures the container that is run when using the result image

from configuration:

Element Type Default value Description
image String gtroless/javacr.io/dis The base image
credHelper String Suffix for the credential helper docker-credential-<credHelper> to authenticate with the Docker registry to pull the base image from. Docker Hub when empty
auth auth Alternative to credHelper credentials

to configuration:

Element Type Default value Description
image String Required The target image
credHelper String Suffix for the credential helper docker-credential-<credHelper> to authenticate with the Docker registry to push the target image to. Docker Hub when empty
auth auth Alternative to credHelper credentials

auth configuration:

Element Type
username String
password String

container configuration:

Element Type Default value Description
jvmFlags List JVM arguments to be passed to the Java application
args List Parameters to be passed to the main method of the Java application

See jib-maven-plugin’s Extended Usage tables for more options.

5. Building the Docker Image Using Jib

  • Let’s first set a specific release version to the project instead of a snapshot before building it:

1

mvn clean versions:set -DnewVersion=1.0.1

2

...

3

[INFO] Processing com.asimio.demo:springboot2-docker-demo

4

[INFO]     Updating project com.asimio.demo:springboot2-docker-demo

5

[INFO]         from version 0-SNAPSHOT to 1.0.1

6

[INFO]

7

[INFO] ------------------------------------------------------------------------

8

[INFO] BUILD SUCCESS

9

[INFO] ------------------------------------------------------------------------

10

...
  • Now let’s build the Spring Boot artifact:

1

mvn package

2

...

3

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

4

[INFO]

5

[INFO]

6

[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ springboot2-docker-demo ---

7

[INFO] Building jar: /Users/ootero/Downloads/ttt/springboot2-docker-demo/target/springboot2-docker-demo-1.0.1.jar

8

[INFO]

9

[INFO] --- spring-boot-maven-plugin:2.0.3.RELEASE:repackage (default) @ springboot2-docker-demo ---

10

[INFO] ------------------------------------------------------------------------

11

[INFO] BUILD SUCCESS

12

[INFO] ------------------------------------------------------------------------

13

...

Tip: Before building a Docker image containing this Spring Boot application, you might also want to deploy this artifact to an S3 bucket.

  • This step is not required to build a Docker image using Jib. Still, let’s export to a Docker context to take a look at how the application and its dependencies are laid out:

1

mvn jib:exportDockerContext

2

...

3

[INFO] --- jib-maven-plugin:0.9.7:exportDockerContext (default-cli) @ springboot2-docker-demo ---

4

[INFO] Created Docker context at /Users/ootero/Downloads/ttt/springboot2-docker-demo/target/jib-docker-context

5

[INFO] ------------------------------------------------------------------------

6

[INFO] BUILD SUCCESS

7

[INFO] ------------------------------------------------------------------------

8

...

The Docker context is created at target/jib-docker-context unless -Djib.dockerDir VM argument is passed:

1

ls target/jib-docker-context/

2

Dockerfileclasseslibsresourcessnapshot-libs

Note: The content of target/jib-docker-context could be use to build a Docker image using

docker build -t asimio/springboot2-docker-demo:1.0.1 target/jib-docker-context

command. But the purpose of this post is to show how to build a Docker image without the need of a Docker daemon.

This is how the Dockerfile looks:

1

cat target/jib-docker-context/Dockerfile

2

FROM openjdk:8u171-alpine

3

4

COPY libs /app/libs/

5

COPY snapshot-libs /app/libs/

6

COPY resources /app/resources/

7

COPY classes /app/classes/

8

9

ENTRYPOINT ["java","-Xms512m","-Xmx512m","-cp","/app/libs/*:/app/resources/:/app/classes/","com.asimio.api.ApiDockerDemoApplication"]

10

CMD []

Notice jib-maven-plugin Maven plugin is extracting the application dependencies, properties files and classes. I wouldn’t expect this to be a problem for Spring Boot applications. Also, this plugin auto detects the main Java class.

  • As mentioned earlier, Jib can be also used to build to a Docker daemon. Even so, this blog post only covers building an image when Docker is not installed. Let’s then configure authentication in Maven’s settings.xml:

1

<settings>

2

...

3

  <servers>

4

...

5

    <server>

6

      <id>registry.hub.docker.com</id>

7

      <username>xxxx</username>

8

      <password>xxxx</password>

9

    </server>

10

...

11

  </servers>

12

...

13

</settings>

The id element should be set to the Docker registry server you would like to push the image to.

Note: It’s recommended to encrypt passwords in Maven’s settings.xml.

  • And finally, let’s build and push the Docker image:

1

mvn jib:build

2

...

3

[INFO] --- jib-maven-plugin:0.9.7:build (default-cli) @ springboot2-docker-demo ---

4

[INFO]

5

[INFO] Containerizing application to asimio/springboot2-docker-demo:1.0.1...

6

[INFO]

7

[INFO] Retrieving registry credentials for registry.hub.docker.com...

8

[INFO] Getting base image openjdk:8u171-alpine...

9

[INFO] Building dependencies layer...

10

[INFO] Building resources layer...

11

[INFO] Building classes layer...

12

[INFO] Retrieving registry credentials for registry.hub.docker.com...

13

[INFO] Finalizing...

14

[INFO]

15

[INFO] Container entrypoint set to [java, -Xms512m, -Xmx512m, -cp, /app/libs/*:/app/resources/:/app/classes/, com.asimio.api.ApiDockerDemoApplication]

16

[INFO]

17

[INFO] Built and pushed image as asimio/springboot2-docker-demo:1.0.1

18

[INFO]

19

[INFO] ------------------------------------------------------------------------

20

[INFO] BUILD SUCCESS

21

[INFO] ------------------------------------------------------------------------

22

...

asimio/springboot2-docker-demo:1.0.1 image is now available at https://hub.docker.com/r/asimio/springboot2-docker-demo/.

6. Running a Docker Container

1

docker run asimio/springboot2-docker-demo:1.0.1

2

Unable to find image 'asimio/springboot2-docker-demo:1.0.1' locally

3

1.0.1: Pulling from asimio/springboot2-docker-demo

4

8e3ba11ec2a2: Pull complete

5

311ad0da4533: Pull complete

6

df312c74ce16: Pull complete

7

65d8ca522f0b: Pull complete

8

d36ff9619551: Pull complete

9

f9f857caf541: Pull complete

10

Digest: sha256:ce7afa5a5bb13bbdcd21107e9dccd2f7a4be2f8591e39df60c34c068a0f28b9d

11

Status: Downloaded newer image for asimio/springboot2-docker-demo:1.0.1

12

...

13

2018-07-31 04:42:49.101  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''

14

2018-07-31 04:42:49.109  INFO 1 --- [           main] com.asimio.api.ApiDockerDemoApplication  : Started ApiDockerDemoApplication in 7.426 seconds (JVM running for 8.273)

Successfully pulled the public image and started a container with a Spring Boot application.

Google’s Jib is still beta but under active development. Give Jib try, it’s a good alternative to Fabric8’s docker-maven-plugin, Spotify’s docker-maven-plugin, and good old docker build -t ... command.

Stay tuned, I’ll also cover pulling/pushing Docker images from/to private AWS ECR.

Thanks for reading and as always, feedback is very much appreciated. If you found this post helpful and would like to receive updates when content like this gets published, sign up to the newsletter.

7. Source Code

Accompanying source code for this blog post can be found here.

8. References

Learn how to implement some solutions to tackle on the issues of time series forecasting at scale, including continuous accuracy evaluation and algorithm hyperparameters optimization. Watch now!

Presented by InfluxData