{"id":18429134,"url":"https://github.com/openliberty/guide-spring-boot","last_synced_at":"2025-08-20T19:22:57.231Z","repository":{"id":35711421,"uuid":"138080451","full_name":"OpenLiberty/guide-spring-boot","owner":"OpenLiberty","description":"A guide on how to containerize, package, and run a Spring Boot application on an Open Liberty server without modification.","archived":false,"fork":false,"pushed_at":"2025-03-05T20:13:34.000Z","size":15891,"stargazers_count":21,"open_issues_count":1,"forks_count":14,"subscribers_count":5,"default_branch":"prod","last_synced_at":"2025-03-22T21:51:09.484Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://openliberty.io/guides/spring-boot.html","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenLiberty.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-20T20:05:58.000Z","updated_at":"2025-03-05T20:13:39.000Z","dependencies_parsed_at":"2024-02-15T21:24:37.045Z","dependency_job_id":"a0b81957-fbe0-44a3-aab5-d7600fae23df","html_url":"https://github.com/OpenLiberty/guide-spring-boot","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-spring-boot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-spring-boot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-spring-boot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-spring-boot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenLiberty","download_url":"https://codeload.github.com/OpenLiberty/guide-spring-boot/tar.gz/refs/heads/prod","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247697945,"owners_count":20981277,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T05:15:58.304Z","updated_at":"2025-04-07T17:32:47.646Z","avatar_url":"https://github.com/OpenLiberty.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"// Copyright (c) 2019, 2025 IBM Corporation and others.\n// Licensed under Creative Commons Attribution-NoDerivatives\n// 4.0 International (CC BY-ND 4.0)\n//   https://creativecommons.org/licenses/by-nd/4.0/\n//\n// Contributors:\n//     IBM Corporation\n//\n:page-layout: guide-multipane\n:projectid: spring-boot\n:page-duration: 20 minutes\n:page-releasedate: 2019-11-04\n:page-majorupdateddate: 2025-01-09\n:page-description: Learn how to containerize, package, and run a Spring Boot application on Open Liberty.\n:page-tags: ['docker']\n:page-related-guides: ['rest-intro', 'containerize']\n:page-permalink: /guides/{projectid}\n:common-includes: https://raw.githubusercontent.com/OpenLiberty/guides-common/prod\n:source-highlighter: prettify\n:page-seo-title: Deploying a Spring Boot application\n:page-seo-description: A tutorial with examples on how to containerize, package, and run a Spring Boot application in a Docker container on an Open Liberty server.\n:guide-author: Open Liberty\n= Containerizing, packaging, and running a Spring Boot application\n\n[.hidden]\nNOTE: This repository contains the guide documentation source. To view the guide in published form, view it on the https://openliberty.io/guides/{projectid}.html[Open Liberty website].\n\nLearn how to containerize, package, and run a Spring Boot application on Open Liberty without modification.\n\n== What you'll learn\n\nThe starting point of this guide is the finished application from the https://spring.io/guides/gs/spring-boot/[Building an Application with Spring Boot^] guide. If you are not familiar with Spring Boot, complete that guide first. Java 21 is required to run this project.\n\nYou will learn how to use the `springBootUtility` command to deploy a Spring Boot application in Docker on Open Liberty 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. Optionally, you will learn how to use Liberty InstantOn with your Spring Boot application for faster startup.\n\nYou will also learn how to run the Spring Boot application locally with Open Liberty, and how to package it so that it is embedded with an Open Liberty server package.\n\n[role='command']\ninclude::{common-includes}/gitclone.adoc[]\n\n\n== Building and running the application\n\nFirst, build the initial Spring Boot application into an executable JAR file. Navigate to the `start` directory and run the Maven package command:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role='command']\n```\ncd start \nmvnw.cmd package\n```\n--\n\n[.tab_content.mac_section]\n--\n[role='command']\n```\ncd start\n./mvnw package\n```\n--\n\n[.tab_content.linux_section]\n--\n[role='command']\n```\ncd start\n./mvnw package\n```\n--\n\nYou can now run the application in the embedded Tomcat web container by executing the JAR file that you built:\n\n[role='command']\n```\njava -jar target/guide-spring-boot-0.1.0.jar\n```\n\nAfter you see the following messages, the application is ready:\n[role='no_copy']\n----\n... INFO ... [ main] com.example.springboot.Application : Started Application in 2.511 seconds (process running for 3.24)\nLet's inspect the beans provided by Spring Boot:\napplication\n...\nwelcomePageHandlerMapping\nwelcomePageNotAcceptableHandlerMapping\n----\n\n// Static guide instruction\nifndef::cloud-hosted[]\nGo to the http://localhost:8080/hello[^] URL to access the application.\n\nThe following output is displayed in your browser:\n[role='no_copy']\n----\nGreetings from Spring Boot!\n----\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nOpen another command-line session by selecting **Terminal** \u003e **New Terminal** from the menu of the IDE. Run the following command to access the application:\n```bash\ncurl http://localhost:8080/hello\n```\n\nThe following output is returned:\n```\nGreetings from Spring Boot!\n```\nendif::[]\n\nWhen you need to stop the application, press `CTRL+C` in the command-line session where you ran the application.\n\n== Building and running the application in a Docker container\n\nYou 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 https://openliberty.io/guides/containerize.html[Containerizing microservices^] guide.\n\nLearn more about Docker on the https://www.docker.com/why-docker[official Docker website^].\n\nInstall Docker by following the instructions in the https://docs.docker.com/engine/install[official Docker documentation^].\n\nNavigate to the `start` directory. \n\n[role=\"code_command hotspot file=0\", subs=\"quotes\"] \n---- \n#Create the `Dockerfile` in the `start` directory.#\n`Dockerfile`\n---- \n\nDockerfile\n[source, Text, linenums, role='code_column']\n---- \ninclude::finish/Dockerfile[]\n---- \n\nThis Dockerfile is written in two main stages. For more information about multi-stage Dockerfiles, see the documentation on the https://docs.docker.com/develop/develop-images/multistage-build/[official Docker website^].\n\nThe first stage copies the [hotspot=copyJar]`guide-spring-boot-0.1.0.jar` Spring Boot application to the [hotspot=7 file=0]`/staging` temporary directory, \nand then uses the Open Liberty [hotspot=springBootUtility]`springBootUtility` command to thin the application. For more information about the `springBootUtility` command, see the https://openliberty.io/docs/latest/reference/command/springbootUtility-thin.html[springBootUtility documentation^].\n\nThe second stage begins with the [hotspot=OLimage2 file=0]`Open Liberty Docker image`. The Dockerfile copies the Liberty [hotspot=serverXml file=0]`server.xml` configuration 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 [hotspot=libcache file=0]`lib.index.cache` directory and the [hotspot=thinjar file=0]`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.\n\n\n\nUse the following command to build the Docker image:\n[role='command']\n```\ndocker build -t springboot .\n```\n\nTo verify that the images are built, run the `docker images` command to list all local Docker images:\n\n[role='command']\n```\ndocker images\n```\n\nYour `springboot` image appears in the list of Docker images:\n[role='no_copy']\n```\nREPOSITORY    TAG       IMAGE ID         CREATED           SIZE\nspringboot    latest    3a5492c0cbeb     27 seconds ago    485MB\n```\n\nNow, you can run the Spring Boot application in a Docker container:\n[role='command']\n```\ndocker run -d --name springBootContainer --rm -p 9080:9080 -p 9443:9443 springboot\n```\n\nBefore you access your application from the browser, run the `docker ps` command to make sure that your container is running:\n\n[role='command']\n----\ndocker ps\n----\n\nYou see an entry similar to the following example:\n[role='no_copy']\n----\nCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                            NAMES\ne33532aa07d6        springboot          \"/opt/ol/helpers/run…\"   7 seconds ago       Up 2 seconds        0.0.0.0:9080-\u003e9080/tcp, 0.0.0.0:9443-\u003e9443/tcp   springBootContainer\n----\n\nYou can watch the application start by monitoring the logs:\n[role='command']\n```\ndocker logs springBootContainer\n```\n\nWait several seconds for the following message, which indicates that Liberty’s startup is complete:\n[role='no_copy']\n----\n...\nCWWKZ0001I: Application thin-guide-spring-boot-0.1.0 started in 8.033 seconds.\n...\nCWWKF0011I: The defaultServer server is ready to run a smarter planet.\nThe defaultServer server started in 11.065 seconds.\n----\n\nNote that the `thin-guide-spring-boot-0.1.0` application took 8.033 seconds to start.\n\n// Static guide instruction\nifndef::cloud-hosted[]\nAfter the application starts, go to the http://localhost:9080/hello[^] URL to access the application.\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nAfter the application starts, run the following command to access the application:\n\n```bash\ncurl http://localhost:9080/hello\n```\nendif::[]\n\nAfter you are finished checking out the application, stop your container by running the following command:\n\n[role='command']\n```\ndocker stop springBootContainer\n```\n\nifndef::cloud-hosted[]\n== Optional: Faster container startup with InstantOn\n\nLiberty InstantOn provides fast startup times for MicroProfile and Jakarta EE applications. In this section, you’ll learn how to build an InstantOn image that provides fast startup times. Your application can start in milliseconds, without compromising on throughput, memory, development-production parity, or Java language features.\n\nLiberty InstantOn requires a Linux system with kernel version 5.9 or greater. You can run the following command to check the kernel version of your system:\n\n[role='command']\n```\nuname -r\n```\n\nIf your kernel version is older than 5.9, you can skip this section and move on to the \u003c\u003crunning-the-application-on-open-liberty\u003e\u003e section.\n\nThe https://openliberty.io/docs/latest/reference/feature/crac.html[Coordinated Restore at Checkpoint^] (`crac`) Liberty feature enables applications to use the Liberty InstantOn implementation of the https://javadoc.io/doc/org.crac/crac/1.4.0/index.html[org.crac^] APIs. When the `org.crac` APIs are enabled, checkpoint and restore can work with applications written using the Spring Framework.\n\n[role=\"code_command hotspot file=0\", subs=\"quotes\"]\n----\n#Replace the `Dockerfile` in the `start` directory.#\n`Dockerfile`\n----\n\nDockerfile\n[source, Text, linenums, role='code_column']\n----\ninclude::instantOn/Dockerfile[]\n----\n\ncrac.xml\n[source, xml, linenums, role='code_column']\n----\ninclude::finish/src/main/liberty/instantOn/crac.xml[]\n----\n\nThe [hotspot=cracXml file=0]`COPY` command copies the provided `crac.xml` configuration file to the Liberty `configDropins` configuration directory. The `crac.xml` file enables the [hotspot=crac file=1]`crac` feature to the Liberty instance.\n\nRun the following command to rebuild the Docker image:\n[role='command']\n```\ndocker build -t springboot .\n```\n\nTo take a checkpoint of the application process with the `afterAppStart` option, run the following command:\n\n[role='command']\n```\ndocker run \\\n  --name springBootCheckpointContainer \\\n  --privileged \\\n  --env WLP_CHECKPOINT=afterAppStart \\\n  springboot\n```\n\nWhen the application process checkpoint completes, the `springBootCheckpointContainer` application container is stopped and exits. The stopped `springBootCheckpointContainer` container contains the data from the InstantOn checkpoint process. Take this checkpoint process data and commit it to an application container image layer called `springboot-instanton`, run the following commands:\n\n[role='command']\n```\ndocker commit springBootCheckpointContainer springboot-instanton\ndocker rm springBootCheckpointContainer\n```\n\nThe stopped `springBootCheckpointContainer` container is no longer needed and can safely be removed.\n\nTo verify that the InstantOn image is built, run the `docker images` command to list all local Docker images:\n\n[role='command']\n```\ndocker images\n```\n\nYour `springboot-instanton` image appears in the list of Docker images.\n\n[role='no_copy']\n```\nREPOSITORY             TAG      IMAGE ID       CREATED          SIZE\nspringboot-instanton   latest   c4aabcdd64bf   20 seconds ago   583MB\nspringboot             latest   3a5492c0cbeb   14 minutes ago   484MB\n```\n\nRun the `springboot-instanton` InstantOn application image by running the following command:\n\n[role='command']\n```\ndocker run \\\n  --rm -d \\\n  --name springBootContainer \\\n  --cap-add=CHECKPOINT_RESTORE \\\n  --cap-add=SETPCAP \\\n  --security-opt seccomp=unconfined \\\n  -p 9080:9080 \\\n  springboot-instanton\n```\n\nRun the following command to see the container logs:\n\n[role='command']\n```\ndocker logs springBootContainer\n```\n\nYou see more logs from Spring for restoring. Liberty’s startup is complete in less than a second. It shows a faster startup time of 0.874 seconds than the original `springboot` image that you built in the previous section.\n\n[role='no_copy']\n----\n2024-11-22T16:33:43.349Z  INFO 1027 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor  : Restarting Spring-managed lifecycle beans after JVM restore\n...\n2024-11-22T16:33:43.562Z  INFO 1027 --- [ecutor-thread-1] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 135784 ms\n2024-11-22T16:33:43.568Z  INFO 1027 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor  : Spring-managed lifecycle restart completed (restored JVM running for 525 ms)\n...\nCWWKZ0001I: Application thin-guide-spring-boot-0.1.0 started in 0.874 seconds.\n...\nCWWKF0011I: The defaultServer server is ready to run a smarter planet.\nThe defaultServer server started in 0.897 seconds.\n----\n\nGo to the http://localhost:9080/hello[^] URL to access the application.\n\nAfter you are finished checking out the application, stop your container by running the following command:\n\n[role='command']\n```\ndocker stop springBootContainer\n```\n\nIf you use Podman instead of Docker, you can build your InstantOn image in a simplified way. Read the https://openliberty.io/docs/latest/instanton.html#checkpoint_script[Building the InstantOn image with Podman and the checkpoint.sh script^] documentation.\n\nTo learn more about the Liberty InstantOn feature, see the https://openliberty.io/docs/latest/instanton.html[Faster startup for containerized applications with Open Liberty InstantOn^] documentation.\n\nendif::[]\n\n\n== Running the application on Open Liberty\n\nNext, you will run the Spring Boot application locally on Open Liberty by updating the `pom.xml` file.\n\nThe [hotspot file=0]`pom.xml` was created for you in this directory. \n\n[role=\"code_command hotspot file=0\", subs=\"quotes\"] \n---- \n#Update the `Maven POM` file in the `start` directory.#\n`pom.xml`\n---- \n\npom.xml\n[source, XML, linenums, role='code_column hide_tags=packageFile,include,packageGoals'] \n---- \ninclude::finish/pom.xml[]\n---- \n\n[role=\"edit_command_text\"]\nAdd the [hotspot=libertyMavenPlugin file=0]`liberty-maven-plugin` to the [hotspot file=0]`pom.xml` file.\n\nThe `liberty-maven-plugin` downloads and installs Open Liberty to the `target/liberty` directory. The [hotspot=installAppPackages file=0]`installAppPackages` configuration element in the [hotspot file=0]`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 [hotspot=installAppPackages file=0]`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 [hotspot=appsDirectory file=0]`applications` directory and shared library directory.\n\nTo run the Spring Boot application, the Open Liberty instance needs to be correctly configured. By default, the `liberty-maven-plugin` picks up the Liberty `server.xml` configuration file from the `src/main/liberty/config` directory.\n\n[role=\"code_command hotspot file=1\", subs=\"quotes\"] \n---- \n#Create the Liberty `server.xml` configuration file.#\n`src/main/liberty/config/server.xml`\n---- \n\nserver.xml\n[source, XML, linenums, role='code_column'] \n---- \ninclude::finish/src/main/liberty/config/server.xml[]\n---- \n\nThe [hotspot=servlet file=1]`servlet` and [hotspot=springboot file=1]`springBoot` features are required for the Liberty instance to run the Spring Boot application. The application port is specified as [hotspot=httpport file=1]`9080` and the application is configured as a [hotspot=springBootApplication file=1]`springBootApplication` element. For more information, see the https://www.openliberty.io/docs/latest/reference/config/springBootApplication.html[springBootApplication element documentation^].\n\nIf you didn't build the Spring Boot application, run the `package` goal:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role='command']\n```\nmvnw.cmd package\n```\n--\n\n[.tab_content.mac_section]\n--\n[role='command']\n```\n./mvnw package\n```\n--\n\n[.tab_content.linux_section]\n--\n[role='command']\n```\n./mvnw package\n```\n--\n\nNext, run the `liberty:run` goal. This goal creates the Open Liberty instance, installs required features, deploys the Spring Boot application to the Open Liberty instance, and starts the application.\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role='command']\n```\nmvnw.cmd liberty:run\n```\n--\n\n[.tab_content.mac_section]\n--\n[role='command']\n```\n./mvnw liberty:run\n```\n--\n\n[.tab_content.linux_section]\n--\n[role='command']\n```\n./mvnw liberty:run\n```\n--\n\nAfter you see the following message, your Liberty instance is ready:\n[role=\"no_copy\"]\n----\nThe defaultServer server is ready to run a smarter planet.\n----\n\n// Static guide instruction\nifndef::cloud-hosted[]\nGo to the http://localhost:9080/hello[^] URL to access the application.\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nIn another command-line sesssion, run the following command to access the application:\n\n```bash\ncurl http://localhost:9080/hello\n```\nendif::[]\n\nAfter you finish exploring the application, press `CTRL+C` to stop the Open Liberty instance. Alternatively, you can run the `liberty:stop` goal from the `start` directory in a separate command-line session:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role='command']\n```\nmvnw.cmd liberty:stop\n```\n--\n\n[.tab_content.mac_section]\n--\n[role='command']\n```\n./mvnw liberty:stop\n```\n--\n\n[.tab_content.linux_section]\n--\n[role='command']\n```\n./mvnw liberty:stop\n```\n--\n\n== Packaging the application embedded with Open Liberty\n\nYou 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.\n\n[role=\"code_command hotspot file=0\", subs=\"quotes\"] \n---- \n#Update the Maven POM file in the `start` directory.#\n`pom.xml`\n----\n\npom.xml\n[source, XML, linenums, role='code_column'] \n---- \ninclude::finish/pom.xml[]\n---- \n\n[role=\"edit_command_text\"]\nAdd the [hotspot=include file=0]`include` and [hotspot=packageFile file=0]`packageName` configuration elements, and the [hotspot=packageGoals file=0]`executions` element to the `pom.xml` file. \n\nThe [hotspot=include file=0]`include` configuration element 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.\n\nThe [hotspot=packageFile file=0]`packageName` configuration element specifies that the application is generated as a `GSSpringBootApp.jar` file.\n\nThe [hotspot=packageGoals file=0]`executions` element specifies the required Open Liberty Maven goals to generate the application that is embedded with Open Liberty. \n\nNext, run the Maven `package` goal:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role='command']\n```\nmvnw.cmd package\n```\n--\n\n[.tab_content.mac_section]\n--\n[role='command']\n```\n./mvnw package\n```\n--\n\n[.tab_content.linux_section]\n--\n[role='command']\n```\n./mvnw package\n```\n--\n\nRun the repackaged Spring Boot application. This JAR file was defined previously in the [hotspot file=0]`pom.xml` file.\n\n[role='command']\n```\njava -jar target/GSSpringBootApp.jar\n```\n\nAfter you see the following message, your Liberty instance is ready:\n\n[role=\"no_copy\"]\n----\nThe defaultServer server is ready to run a smarter planet.\n----\n\n// Static guide instruction\nifndef::cloud-hosted[]\nGo to the http://localhost:9080/hello[^] URL to access the application.\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nIn another command-line sesssion, run the following command to access the application:\n```bash\ncurl http://localhost:9080/hello\n```\nendif::[]\n\nWhen you need to stop the application, press `CTRL+C`.\n\n\n== Great work! You're done!\n\nYou just ran a basic Spring Boot application with Open Liberty.\n\ninclude::{common-includes}/attribution.adoc[subs=\"attributes\"]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-spring-boot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenliberty%2Fguide-spring-boot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-spring-boot/lists"}