Containerizing, packaging, and running a Spring Boot application

duration 20 minutes

Prerequisites:

Learn how to containerize, package, and run a Spring Boot application on an Open Liberty server without modification.

What you’ll learn

The starting point of this guide is the finished application from Spring’s Building an Application with Spring Boot guide. If you are not familiar with Spring Boot, complete that guide first. Java 8 is required to run this project.

You will learn how to use the springBootUtility command to deploy a Spring Boot application in Docker on an Open Liberty server without modification. This command stores the dependent library JAR files of the application to the target library cache, and packages the remaining application artifacts into a thin application JAR file.

You will also learn how to run the Spring Boot application locally with an Open Liberty server, and how to package it so that it is embedded with an Open Liberty server.

Getting started

The fastest way to work through this guide is to clone the Git repository and use the projects that are provided inside:

git clone https://github.com/openliberty/guide-spring-boot.git
cd guide-spring-boot

The start directory contains the starting project that you will build upon.

The finish directory contains the finished project that you will build.

Building and running the application

First, build the initial Spring Boot application into an executable JAR file. Navigate to the start directory and run the Maven package command:

cd start
./mvnw package

You can now run the application in the embedded Tomcat web container by executing the JAR file that you built:

java -jar target/guide-spring-boot-0.1.0.jar

Notice that the console output displays a message about the application running in Tomcat on port 8080.

... INFO ... [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''

Go to the http://localhost:8080/hello URL to access the application.

The following output is displayed in your browser:

Greetings from Spring Boot!

When you need to stop the application, press CTRL+C in the shell session where you ran the application.

Building and running the application in a Docker container

You will build an Open Liberty Docker image to run the Spring Boot application. Using Docker, you can run your thinned application with a few simple commands. For more information on using Open Liberty with Docker, see the Containerizing microservices guide.

Learn more about Docker on the official Docker website.

Install Docker by following the instructions in the official Docker documentation.

Navigate to the start directory.

Create the Dockerfile.
Dockerfile

Dockerfile

 1# Stage and thin the application
 2# tag::OLimage1[]
 3FROM open-liberty as staging
 4# end::OLimage1[]
 5# tag::copyJar[]
 6COPY --chown=1001:0 target/guide-spring-boot-0.1.0.jar \
 7                    /staging/fat-guide-spring-boot-0.1.0.jar
 8# end::copyJar[]
 9# tag::springBootUtility[]
10RUN springBootUtility thin \
11 --sourceAppPath=/staging/fat-guide-spring-boot-0.1.0.jar \
12 --targetThinAppPath=/staging/thin-guide-spring-boot-0.1.0.jar \
13 --targetLibCachePath=/staging/lib.index.cache
14# end::springBootUtility[]
15
16# Build the image
17# tag::OLimage2[]
18FROM open-liberty
19# end::OLimage2[]
20# tag::serverXml[]
21RUN cp /opt/ol/wlp/templates/servers/springBoot2/server.xml /config/server.xml
22# end::serverXml[]
23# tag::libcache[]
24COPY --from=staging /staging/lib.index.cache /lib.index.cache
25# end::libcache[]
26# tag::thinjar[]
27COPY --from=staging /staging/thin-guide-spring-boot-0.1.0.jar \
28                    /config/dropins/spring/thin-guide-spring-boot-0.1.0.jar
29# end::thinjar[]

This Dockerfile is written in two main stages. For more information about multi-stage Dockerfiles, see the documentation on the official Docker website.

The first stage copies the guide-spring-boot-0.1.0.jar Spring Boot application to the /staging temporary directory, and then uses the Open Liberty springBootUtility command to thin the application. For more information about the springBootUtility command, see the springBootUtility documentation.

The second stage begins with the Open Liberty Docker image. The Dockerfile copies the server.xml file from the /opt/ol/wlp/templates directory, which enables Spring Boot and TLS support. Then, the Dockerfile copies the Spring Boot dependent library JAR files that are at the lib.index.cache directory and the thin-guide-spring-boot-0.1.0.jar file. The lib.index.cache directory and the thin-guide-spring-boot-0.1.0.jar file were both generated in the first stage.

Use the following command to build the Docker image:

docker build -t springboot .

To verify that the images are built, run the docker images command to list all local Docker images:

docker images

Your springboot image appears in the list of Docker images:

REPOSITORY    TAG       IMAGE ID         CREATED           SIZE
springboot    latest    d3ffdaa81854     27 seconds ago    486MB

Now, you can run the Spring Boot application in a Docker container:

docker run -d --name springBootContainer -p 9080:9080 -p 9443:9443 springboot

Before you access your application from the browser, run the docker ps command to make sure that your container is running:

docker ps

You see an entry similar to the following example:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                            NAMES
e33532aa07d6        springboot          "/opt/ibm/docker/doc…"   7 seconds ago       Up 2 seconds        0.0.0.0:9080->9080/tcp, 0.0.0.0:9443->9443/tcp   springBootContainer

You can watch the application start by monitoring the logs:

docker logs springBootContainer

After the application starts, go to the http://localhost:9080/hello URL to access the application.

Tearing down the Docker container

To stop and remove your container, run the following commands:

docker stop springBootContainer
docker rm springBootContainer

Running the application on Open Liberty

Next, you will run the Spring Boot application locally on Open Liberty by updating the pom.xml file.

The pom.xml was created for you in this directory.

Update the Maven POM file.
pom.xml

Add the liberty-maven-plugin to the pom.xml file.

pom.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4  <modelVersion>4.0.0</modelVersion>
 5
 6  <groupId>org.springframework</groupId>
 7  <artifactId>guide-spring-boot</artifactId>
 8  <version>0.1.0</version>
 9
10  <parent>
11    <groupId>org.springframework.boot</groupId>
12    <artifactId>spring-boot-starter-parent</artifactId>
13    <version>2.0.3.RELEASE</version>
14  </parent>
15
16  <dependencies>
17    <dependency>
18      <groupId>org.springframework.boot</groupId>
19      <artifactId>spring-boot-starter-web</artifactId>
20    </dependency>
21    <!-- tag::actuator[] -->
22    <dependency>
23      <groupId>org.springframework.boot</groupId>
24      <artifactId>spring-boot-starter-actuator</artifactId>
25    </dependency>
26    <!-- end::actuator[] -->
27    <!-- tag::tests[] -->
28    <dependency>
29      <groupId>org.springframework.boot</groupId>
30      <artifactId>spring-boot-starter-test</artifactId>
31      <scope>test</scope>
32    </dependency>
33    <!-- end::tests[] -->
34  </dependencies>
35
36  <properties>
37    <java.version>1.8</java.version>
38  </properties>
39
40  <build>
41    <plugins>
42      <plugin>
43        <groupId>org.springframework.boot</groupId>
44        <artifactId>spring-boot-maven-plugin</artifactId>
45      </plugin>
46      <plugin>
47        <artifactId>maven-failsafe-plugin</artifactId>
48        <executions>
49          <execution>
50            <goals>
51              <goal>integration-test</goal>
52              <goal>verify</goal>
53            </goals>
54          </execution>
55        </executions>
56      </plugin>
57
58      <!-- Enable Liberty Maven plugin -->
59      <!-- tag::libertyMavenPlugin[] -->
60      <plugin>
61        <groupId>io.openliberty.tools</groupId>
62        <artifactId>liberty-maven-plugin</artifactId>
63        <version>3.1</version>
64        <configuration>
65          <!-- tag::appsDirectory[] -->
66          <appsDirectory>apps</appsDirectory>
67          <!-- end::appsDirectory[] -->
68          <!-- tag::installAppPackages[] -->
69          <installAppPackages>spring-boot-project</installAppPackages>
70          <!-- end::installAppPackages[] -->
71          <!-- tag::include[] -->
72          <include>minify,runnable</include>
73          <!-- end::include[] -->
74          <!-- tag::packageFile[] -->
75          <packageName>GSSpringBootApp</packageName>
76          <!-- end::packageFile[] -->
77        </configuration>
78        <!-- tag::packageGoals[] -->
79        <executions>
80          <execution>
81            <id>package-server</id>
82            <phase>package</phase>
83            <goals>
84              <goal>create</goal>
85              <goal>install-feature</goal>
86              <goal>deploy</goal>
87              <goal>package</goal>
88            </goals>
89          </execution>
90        </executions>
91        <!-- end::packageGoals[] -->
92      </plugin>
93      <!-- end::libertyMavenPlugin[] -->
94      <!-- End of Liberty Maven plugin -->
95
96    </plugins>
97  </build>
98</project>

The liberty-maven-plugin downloads and installs Open Liberty to the target/liberty directory. The <installAppPackages/> configuration tag in the pom.xml file typically takes in the following parameters: dependencies, project, or all. The default value is dependencies, but to install the Spring Boot application to Open Liberty, the value must be spring-boot-project. This value allows Maven to package, thin, and copy the guide-spring-boot-0.1.0.jar application to the Open Liberty runtime applications directory and shared library directory.

To run the Spring Boot application, the Open Liberty server needs to be correctly configured. By default, the liberty-maven-plugin picks up the server configuration file from the src/main/liberty/config directory.

Create the server.xml.
src/main/liberty/config/server.xml

The servlet and springBoot features are required for the Liberty server to run the Spring Boot application. The application port is specified as 9080 and the application is configured as a <springBootApplication />.

server.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<server description="new server">
 3
 4    <featureManager>
 5    <!-- tag::servlet[] -->
 6        <feature>servlet-4.0</feature>
 7    <!-- end::servlet[] -->
 8    <!-- tag::springboot[] -->
 9        <feature>springBoot-2.0</feature>
10    <!-- end::springboot[] -->
11    </featureManager>
12
13    <!-- tag::httpport[] -->
14    <httpEndpoint id="defaultHttpEndpoint"
15                  httpPort="9080"
16                  httpsPort="9443" />
17    <!-- end::httpport[] -->
18
19    <!-- tag::springBootApplication[] -->
20    <springBootApplication id="guide-spring-boot"
21                           location="thin-guide-spring-boot-0.1.0.jar"
22                           name="guide-spring-boot" />
23    <!-- end::springBootApplication[] -->
24
25</server>

If you didn’t build the Spring Boot application, run the package goal:

./mvnw package

Next, run the liberty:run goal. This goal creates the Open Liberty server, installs required features, deploys the Spring Boot application to the Open Liberty server, and starts the application.

./mvnw liberty:run

Go to the http://localhost:9080/hello URL to access the application.

After you finish exploring the application, press CTRL+C to stop the Open Liberty server. Alternatively, you can run the liberty:stop goal from the start directory in a separate shell session:

./mvnw liberty:stop

Packaging the application embedded with Open Liberty

You can update the pom.xml file to bind more Open Liberty Maven goals to the package phase. Binding these goals to the package phase allows the Maven package goal to build a Spring Boot application that is embedded with Open Liberty.

Update the Maven POM file.
pom.xml

Add the <include/> and <packageFile/> configuration tags, and the <executions/> tag to the pom.xml file.

pom.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4  <modelVersion>4.0.0</modelVersion>
 5
 6  <groupId>org.springframework</groupId>
 7  <artifactId>guide-spring-boot</artifactId>
 8  <version>0.1.0</version>
 9
10  <parent>
11    <groupId>org.springframework.boot</groupId>
12    <artifactId>spring-boot-starter-parent</artifactId>
13    <version>2.0.3.RELEASE</version>
14  </parent>
15
16  <dependencies>
17    <dependency>
18      <groupId>org.springframework.boot</groupId>
19      <artifactId>spring-boot-starter-web</artifactId>
20    </dependency>
21    <!-- tag::actuator[] -->
22    <dependency>
23      <groupId>org.springframework.boot</groupId>
24      <artifactId>spring-boot-starter-actuator</artifactId>
25    </dependency>
26    <!-- end::actuator[] -->
27    <!-- tag::tests[] -->
28    <dependency>
29      <groupId>org.springframework.boot</groupId>
30      <artifactId>spring-boot-starter-test</artifactId>
31      <scope>test</scope>
32    </dependency>
33    <!-- end::tests[] -->
34  </dependencies>
35
36  <properties>
37    <java.version>1.8</java.version>
38  </properties>
39
40  <build>
41    <plugins>
42      <plugin>
43        <groupId>org.springframework.boot</groupId>
44        <artifactId>spring-boot-maven-plugin</artifactId>
45      </plugin>
46      <plugin>
47        <artifactId>maven-failsafe-plugin</artifactId>
48        <executions>
49          <execution>
50            <goals>
51              <goal>integration-test</goal>
52              <goal>verify</goal>
53            </goals>
54          </execution>
55        </executions>
56      </plugin>
57
58      <!-- Enable Liberty Maven plugin -->
59      <!-- tag::libertyMavenPlugin[] -->
60      <plugin>
61        <groupId>io.openliberty.tools</groupId>
62        <artifactId>liberty-maven-plugin</artifactId>
63        <version>3.1</version>
64        <configuration>
65          <!-- tag::appsDirectory[] -->
66          <appsDirectory>apps</appsDirectory>
67          <!-- end::appsDirectory[] -->
68          <!-- tag::installAppPackages[] -->
69          <installAppPackages>spring-boot-project</installAppPackages>
70          <!-- end::installAppPackages[] -->
71          <!-- tag::include[] -->
72          <include>minify,runnable</include>
73          <!-- end::include[] -->
74          <!-- tag::packageFile[] -->
75          <packageName>GSSpringBootApp</packageName>
76          <!-- end::packageFile[] -->
77        </configuration>
78        <!-- tag::packageGoals[] -->
79        <executions>
80          <execution>
81            <id>package-server</id>
82            <phase>package</phase>
83            <goals>
84              <goal>create</goal>
85              <goal>install-feature</goal>
86              <goal>deploy</goal>
87              <goal>package</goal>
88            </goals>
89          </execution>
90        </executions>
91        <!-- end::packageGoals[] -->
92      </plugin>
93      <!-- end::libertyMavenPlugin[] -->
94      <!-- End of Liberty Maven plugin -->
95
96    </plugins>
97  </build>
98</project>

The <include/> configuration tag specifies the minify, runnable values. The runnable value allows the application to be generated as a runnable JAR file. The minify value packages only what you need from your configuration files without bundling the entire Open Liberty install.

The <packageFile/> configuration tag specifies that the application is generated as a GSSpringBootApp.jar file.

The <executions/> tag specifies the required Open Liberty Maven goals to generate the application that is embedded with Open Liberty.

Next, run the Maven package goal:

./mvnw package

Run the repackaged Spring Boot application. This JAR file was defined previously in the pom.xml file.

java -jar target/GSSpringBootApp.jar

Go to the http://localhost:9080/hello URL to access the application.

When you need to stop the application, press CTRL+C.

Great work! You’re done!

You just ran a basic Spring Boot application with Open Liberty.

Guide Attribution

Containerizing, packaging, and running a Spring Boot application by Open Liberty is licensed under CC BY-ND 4.0

Copied to clipboard
Copy code block
Copy file contents

Prerequisites:

Nice work! Where to next?

What did you think of this guide?

Extreme Dislike Dislike Like Extreme Like

What could make this guide better?

Raise an issue to share feedback

Create a pull request to contribute to this guide

Need help?

Ask a question on Stack Overflow

Like Open Liberty? Star our repo on GitHub.

Star