- Background
- Additional Resources
- Prerequisites
- Run the application
- Examine the internals
- Analyze the application for migration
- Correct Issues
- Re-analyze the application
- Migrate Data source properties
- Bonus: No hassle native image
Hands-on tutorial based on a demo application that builds and runs as either Spring Boot or Quarkus.
This tutorial takes a Spring Boot application using Spring MVC, Spring Data JPA, and a PostgreSQL database and converts it to Quarkus with little-to-no source code changes. It uses the Red Hat Migration Toolkit for Applications to analyze the Spring Boot application and offer suggestions for how to migrate it to Quarkus.
The completed solution to this exercise can be found in this repo's solution
branch.
- Quarkus for Spring Developers eBook
- Quarkus Insights: Quarkus for Spring Developers
- Why should I choose Quarkus over Spring for my microservices?
- Spring Boot on Quarkus - Magic or Madness?
- Evolution of the Quarkus Developer Experience
- Red Hat Migration Toolkit for Applications
- A Java 11 runtime
- A container runtime (i.e. Docker or Podman)
docker
commands are used throughout this example
- Access to the internet
-
Start the required PostgreSQL database:
docker run -it --rm --name tododb -e POSTGRES_USER=todo -e POSTGRES_PASSWORD=todo -e POSTGRES_DB=tododb -p 5432:5432 postgres:14
NOTE: If you see an error related to rate limits (something like
You have reached your pull rate limit
), you need to first do adocker login -u <YOUR_DOCKER_USERNAME>
in order to pull the image. If you don't have a username, you can create a free account. -
Run the application:
./mvnw clean spring-boot:run
You should see the standard Spring Boot Banner:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.0) INFO 33595 --- [ restartedMain] com.acme.todo.TodoApplication : Started TodoApplication in 5.073 seconds (JVM running for 5.544)
-
Open your browser to http://localhost:8080. You should see
-
Play around with the application a bit. Type a new todo into the text box and press
Enter
. That todo will show up in the list:- Click the empty circle next to a todo to complete it, or uncheck it to mark it as incomplete.
- Click the
X
to remove a todo. - The
OpenAPI
link at the bottom of the page will open the OpenAPI 3.0 specification for the application. - The
Swagger UI
link opens the embedded Swagger UI, which can be used to execute some of the RESTful endpoints directly. - The
Prometheus Metrics
link leads to the Prometheus metrics endpoint, which would be scraped intermittently by Prometheus. - The
Health Check
link opens the built-in health check exposed by Spring Boot.
-
Go ahead and play around a bit to see it all in action. Use
CTRL-C
in the terminal to stop the application before proceeding. -
Run
./mvnw clean
to clean things up. -
IMPORTANT! Also make sure to stop the docker daemon running the PostgreSQL database from step 1 before proceeding (you can use
CTRL-C
to stop it).
- Spring MVC for building the REST layer:
- Open
src/main/java/com/acme/todo/rest/TodoController.java
to find the Spring MVC RESTful controller, exposing the various endpoints available to the user interface.
- Open
- Spring Data JPA for defining relational entities as well as storing and retrieving them:
- Open
src/main/java/com/acme/todo/domain/TodoEntity.java
to find the Java Persistence API (JPA), representing the relational table for storing the todos. - Open
src/main/java/com/acme/todo/repository/TodoRepository.java
to find the Spring Data JPA Repository, exposing all of the create, read, update, and delete operations for theTodoEntity
.
- Open
- Spring Boot Actuators for providing operational capabilities, including health checks and metrics gathering.
- SpringDoc OpenAPI 3 for generating and exposing RESTful API information as well as the embedded Swagger UI endpoint.
NOTE: Spring Boot on its own does not have a starter providing this capability.
- Prometheus Micrometer Registry for exposing metrics to Prometheus.
- Open
src/main/resources/META-INF/resources
to find the user interface components used. - Open
src/main/resources/application.properties
to find the application configuration. - Open
src/main/resources/import.sql
to find some SQL that will pre-populate the database table with an initial set of data.
We are going to use the Red Hat Migration Toolkit for Applications (MTA) to analyze the application. MTA can be run in a number of different ways:
- A web application running locally or on some remote machine.
- A command line interface.
- A plugin to most major IDEs.
- A Maven plugin.
For this exercise we have pre-built a container image that runs the command line interface. This approach was chosen to make it easier to run without having to install anything on a local machine.
NOTE: The
Dockerfile.mta
file was used to create the container image being used.
-
On the terminal from the project directory, run one of the following commands based on the operating system you are running:
-
*nix/macos/Windows Subsystem for Linux (WSL):
docker run -it -v $(pwd):/opt/project:z -u $(id -u):$(id -g) quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
NOTE: If using podman, you could use the command
podman run -it -v $(pwd):/opt/project:z,U quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
-
Windows:
- cmd (not PowerShell):
docker run -it -v %cd%:/opt/project quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
- PowerShell:
docker run -it -v ${PWD}:/opt/project quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
- git bash:
winpty docker run -it -v "/$(pwd -W):/opt/project" quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
orwinpty docker run -it -v "/$(cmd //c cd):/opt/project" quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
If all else fails, you can hard-code the path to your current working directory (i.e.
docker run -it -v c:/path/to/spring-to-quarkus-todo:/opt/project quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
).If none of those options work for you, see here for more information on obtaining the current working directory for the
-v
option. - cmd (not PowerShell):
-
-
Once completed you will see something like:
Report created: /opt/project/mta-report/index.html Access it at this URL: file:///opt/project/mta-report/index.html
-
In your browser, open up the newly-created
mta-report/index.html
page within the project. You should see the Application List page: -
Click on project to move to the Dashboard page:
-
Click on the issues tab at the top to move to the Issues page:
The analysis produced by the Migration Toolkit for Applications contains many links to Quarkus documentation explaining various concepts, like datasource configuration, build tools, etc. Feel free to click around and visit some of these links.
Each issue is something that needs to be dealt with to convert the application from Spring to Quarkus. The majority of the issues presented are related to dependencies within the pom.xml
. Let's fix all of those issues first.
-
In the Migration Mandatory section, find and click on the
Replace the Spring Parent POM with Quarkus BOM
issue. This will expand and explain the issue detail: -
Clicking on
pom.xml
will bring up a page describing all the necessary changes needed to the project'spom.xml
.
The first issue is replacing the Spring parent POM with the Quarkus BOM.
Quarkus does not use a parent POM. Instead, Quarkus imports a BOM inside the
<dependencyManagement>
section of the pom
While we're in pom.xml
we may as well fix all the issues related to it.
-
In your editor/IDE, open
pom.xml
-
Find the
<parent>
section and remove it -
In the
<properties>
section, add<quarkus.platform.version>2.9.2.Final</quarkus.platform.version>
-
After the
<properties>
section but before the<dependencies>
section, add the following block:<dependencyManagement> <dependencies> <dependency> <groupId>io.quarkus.platform</groupId> <artifactId>quarkus-bom</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
-
The next issue is
Replace the Spring Web artifact with Quarkus 'spring-web' extension
.In
pom.xml
, find<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
and, according to the Quarkus Spring Web Guide, replace it with
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-spring-web</artifactId> </dependency>
Additionally, the documentation on the issue mentions that Starting with Quarkus version 2.5, the underlying JAX-RS engine must be chosen. The RESTEasy Reactive extension has better performance than the RESTEasy Classic extension, so we will use that.
NOTE: Selecting the RESTEasy Reactive extension does not mean we are (or have to) build a reactive application. It only affects the underlying engine. See RESTEasy Reactive - To block or not to block, Massive performance without headaches, and A UI thread and a worker thread walk into a bar: a microbenchmark story for more information.
In
pom.xml
, add thequarkus-resteasy-reactive-jackson
extension to the<dependencies>
section:<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive-jackson</artifactId> </dependency>
-
The next issue is
Replace the SpringBoot Data JPA artifact with Quarkus 'spring-data-jpa' extension
.In
pom.xml
, find<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
and, according to the Quarkus JPA Guide, replace it with
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-spring-data-jpa</artifactId> </dependency>
-
The next issue is
Spring component springdoc-openapi-ui requires investigation
. SpringDoc OpenAPI is a 3rd party open source library that isn't part of Spring itself. Luckily, there is the Quarkus OpenAPI extension.In
pom.xml
, find<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.6.8</version> </dependency>
and replace it with
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-openapi</artifactId> </dependency>
-
The next issue is
Replace the Spring Boot Actuator dependency with Quarkus Smallrye Health extension
.In
pom.xml
, find<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
and, according to the Quarkus - SmallRye Health Guide, replace it with
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-health</artifactId> </dependency>
-
The next issue is
Replace the 'micrometer-registry-prometheus' dependency with Quarkus 'quarkus-micrometer-registry-prometheus' extension
. Micrometer Metrics are used in Quarkus as well as in Spring Boot, but Quarkus applications need to use the Quarkus Micrometer Metrics Extension.In
pom.xml
, find<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>
and replace it with
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-micrometer-registry-prometheus</artifactId> </dependency>
-
The next issue is
Replace the 'postgresql' dependency with Quarkus 'quarkus-jdbc-postgresql' extension
. Theorg.postgresql:postgresql
dependency needs to be swapped for the Quarkus PostgreSQL extension.In
pom.xml
, find<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency>
and replace it with
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-jdbc-postgresql</artifactId> </dependency>
-
The next issue is
Remove spring-boot-devtools dependency
. Theorg.springframework.boot:spring-boot-devtools
isn't needed. The Spring Boot Developer Tools provides features aiming to enhance developer productivity, such as live reload. These features are part of the core of Quarkus.In
pom.xml
, find<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
and remove it
-
The next issue is
Spring component spring-boot-starter-test requires investigation
.In
pom.xml
, find<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
and, according to the Quarkus testing guide, replace it with
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency>
-
The next issue is
Replace the spring-boot-maven-plugin dependency
. Theorg.springframework.boot:spring-boot-maven-plugin
needs to be changed so that the application is built with Quarkus, both for running on the JVM and in native image.In
pom.xml
, find<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
and replace it with
<build> <plugins> <plugin> <groupId>io.quarkus</groupId> <artifactId>quarkus-maven-plugin</artifactId> <version>${quarkus.platform.version}</version> <extensions>true</extensions> <executions> <execution> <goals> <goal>build</goal> <goal>generate-code</goal> <goal>generate-code-tests</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>${compiler-plugin.version}</version> <configuration> <parameters>true</parameters> </configuration> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>${surefire-plugin.version}</version> <configuration> <systemPropertyVariables> <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> <maven.home>${maven.home}</maven.home> </systemPropertyVariables> </configuration> </plugin> <plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>${surefire-plugin.version}</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> <configuration> <systemPropertyVariables> <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path> <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> <maven.home>${maven.home}</maven.home> </systemPropertyVariables> </configuration> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <id>native</id> <activation> <property> <name>native</name> </property> </activation> <properties> <quarkus.package.type>native</quarkus.package.type> </properties> </profile> </profiles>
NOTE: While this replacement might seem like a lot of XML, it also sets up the application to build a native image using the
native
Maven profile.
Navigate back to the main issues page and find the Remove the SpringBoot @SpringBootApplication annotation
issue, then click on it.
A Spring Boot application also contains a "main" class with the @SpringBootApplication
annotation. A Quarkus application does not have such a class. There are 2 options that can be taken:
- Remove the
src/main/java/com/acme/todo/TodoApplication.java
class
OR
-
Add the
org.springframework.boot:spring-boot-autoconfigure
dependency as anoptional
Maven dependency. Anoptional
dependency is available when an application compiles but is not packaged with the application at runtime. Doing this would allow the application to compile without modification, but you would also need to maintain a Spring version along with the Quarkus application.To use this option, add this to the
<dependencies>
section ofpom.xml
:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.7.0</version> <optional>true</optional> </dependency>
NOTE: This is the option chosen in the
solution
branch of this repository. This option was chosen purely because we did not want to have to change any source code within the project. In a more "real world" scenario, the better option would most likely be option 1.
Some issues that weren't caught by the tool but also need to be fixed:
-
The application uses the AssertJ library for testing. The AssertJ version is managed by the Spring Boot BOM but not by the Quarkus BOM, therefore you need to explicitly declare its version.
In
pom.xml
, find<dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <scope>test</scope> </dependency>
and add
<version>3.23.1.0</version>
. The resulting dependency should be<dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.23.1.0</version> <scope>test</scope> </dependency>
Now that the changes to pom.xml
are complete, save and close it.
When completed, your pom.xml
should look like the pom.xml
in the solution branch.
Now let's re-analyze the application to see how much of the migration has been completed.
-
On the terminal from the project directory, run one of the following commands based on the operating system you are running:
-
*nix/macos/Windows Subsystem for Linux (WSL):
docker run -it -v $(pwd):/opt/project:z -u $(id -u):$(id -g) quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
NOTE: If using podman, you could use the command
podman run -it -v $(pwd):/opt/project:z,U quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
-
Windows:
- cmd (not PowerShell):
docker run -it -v %cd%:/opt/project quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
- PowerShell:
docker run -it -v ${PWD}:/opt/project quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
- git bash:
winpty docker run -it -v "/$(pwd -W):/opt/project" quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
orwinpty docker run -it -v "/$(cmd //c cd):/opt/project" quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
If all else fails, you can hard-code the path to your current working directory (i.e.
docker run -it -v c:/path/to/spring-to-quarkus-todo:/opt/project quay.io/rhappsvcs/spring-to-quarkus-mta-cli:latest
).If none of those options work for you, see here for more information on obtaining the current working directory for the
-v
option. - cmd (not PowerShell):
-
-
Once completed you will see something like:
Report created: /opt/project/mta-report/index.html Access it at this URL: file:///opt/project/mta-report/index.html
-
Clicking back to the Issues tab should only show a few categories of issues. The remainder of the issues are fixed with configuration in the
application.properties
file. -
Before proceeding, let's start the newly-converted Quarkus application in Quarkus's Dev Mode.
-
In the terminal, run
./mvnw clean quarkus:dev
. -
The Quarkus application should start up, and you should see the Quarkus banner:
INFO [io.qua.dat.dep.dev.DevServicesDatasourceProcessor] (build-46) Dev Services for the default datasource (postgresql) started. __ ____ __ _____ ___ __ ____ ______ --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ INFO [io.quarkus] (Quarkus Main Thread) spring-to-quarkus-todo 0.0.1-SNAPSHOT on JVM (powered by Quarkus 2.9.2.Final) started in 18.927s. Listening on: http://localhost:8080 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. INFO [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, hibernate-orm-panache, jdbc-postgresql, micrometer, narayana-jta, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, smallrye-health, smallrye-openapi, spring-data-jpa, spring-di, spring-web, swagger-ui, vertx]
Notice the line
Dev Services for the default datasource (postgresql) started
. Quarkus Dev Services noticed the PostgreSQL extension on the classpath and started a PostgreSQL container image automatically, while also automatically setting all the configuration properties for the application to communicate with it! -
Re-open your browser to http://localhost:8080.
-
You may (or may not) notice a bunch of exceptions in the console log. This is because we haven't finished converting the application. We still need to migrate some Spring datasource configuration.
The other issues relate to properties within src/main/resources/application.properties
.
-
In your browser tab containing the Migration Toolkit analysis, go back to the Issues page and choose the
Replace Spring datasource property key/value pairs with Quarkus properties
issue and then click on thesrc/main/resources/application.properties
link. -
In your editor/IDE, open
src/main/resources/application.properties
-
The first issue is
Replace Spring JPA Hibernate property with Quarkus property
In
src/main/resources/application.properties
, findspring.jpa.hibernate.ddl-auto=create-drop
and replace withquarkus.hibernate-orm.database.generation=drop-and-create
according to the Quarkus Hibernate ORM and JPA Guide. This will allow Quarkus (& Hibernate under the covers) to automatically create the database schema upon startup. -
The next issue is
Replace Spring datasource property key/value pairs with Quarkus properties
.In
src/main/resources/application.properties
, findspring.datasource.url=jdbc:postgresql://localhost:5432/tododb
and remove it completelyAs you saw, Quarkus Dev Services will automatically create the database for us and bind it to our application.
Similarly, find and remove
spring.datasource.username=todo
andspring.datasource.password=todo
as well -
The next issue is
Replace Spring OpenAPI endpoint mapping
.In
src/main/resources/application.properties
, findspringdoc.api-docs.path=/openapi
and replace it with
quarkus.smallrye-openapi.path=/openapi
to map the default Quarkus OpenAPI endpoint from
/q/openapi
to/openapi
. -
The next issue is
Replace Spring Swagger endpoint mapping
.In
src/main/resources/application.properties
, findspringdoc.swagger-ui.path=/swagger-ui
and replace it with
quarkus.swagger-ui.path=/swagger-ui
to map the default Quarkus Swagger UI page from
/q/swagger-ui
to/swagger-ui
.Additionally, add
quarkus.swagger-ui.always-include=true
so that Quarkus will always expose the Swagger UI endpoint. By default, it is only exposed in Dev Mode. -
The next issue is
Replace Spring Prometheus Metrics endpoint mapping
.In
src/main/resources/application.properties
, addquarkus.micrometer.export.prometheus.path=/actuator/prometheus
to map the default Quarkus Prometheus metrics endpoint from/q/metrics
to/actuator/prometheus
. -
The next issue is
Replace Spring Health endpoint mapping
.In
src/main/resources/application.properties
, addquarkus.smallrye-health.root-path=/actuator/health
to map the default Quarkus health endpoint from/q/health
to/actuator/health
.Additionally, find and remove
management.endpoints.web.exposure.include=prometheus,health
.
There are a couple of other properties that the analysis didn't find.
-
Add
quarkus.datasource.metrics.enabled=true
so that Quarkus will automatically expose datasource-related metrics to Micrometer. -
Now, go back to your browser tab containing the http://localhost:8080 page and refresh it. Magically the page should load and no exceptions in the console! Everything should work as it did before!
Quarkus Dev Mode has seamlessly redeployed your application while also creating the necessary schema and even importing sample data from
src/main/resources/import.sql
. -
Navigate to http://localhost:8080/q/dev (or in your terminal where Dev Mode is running, press
d
) to view the Quarkus Dev UI, a landing page for interacting with your application. All extensions used by the application should show up here along with links to their documentation. Some extensions provide the ability to interact and modify configuration right from the UI.Continuous testing can be enabled and controlled from within the UI. A video demo is available showcasing continuous testing features.
-
Hit
CTRL-C
(or pressq
) in your terminal once done.
As a bonus exercise, let's create and run a Quarkus native image. Writing this exercise we don't know what host OS each individual is using, so we will use container images to facilitate building the native executable as a Linux executable, and then create a coontainer image from it. This will also alleviate the need to install GraalVM on our local machines.
The easiest way to create a container image containing a native executable is to leverage one of the Quarkus container-image extensions. If one of those extensions is present, then creating a container image for the native executable is essentially a matter of executing a single command.
NOTE: Native image creation is a CPU and memory-intensive operation. It may or may not work depending on your hardware specs. You may need at lease 6 GB of RAM allocated to your Docker daemon.
Since we already have a Docker runtime we'll use the Docker container image extension to perform the container image build.
-
To install the extension into the project, return to the terminal and run
./mvnw quarkus:add-extension -Dextensions="container-image-docker"
-
Since this is an existing non-Quarkus application, we need to create the
Dockerfile
for the native image.If we had created a new Quarkus application from Code Quarkus, this would have been created for us.
-
Create the directory
src/main/docker
-
Inside
src/main/docker
, create the fileDockerfile.native
-
Paste in the following into
Dockerfile.native
:FROM registry.access.redhat.com/ubi8/ubi-minimal:8.5 WORKDIR /work/ RUN chown 1001 /work \ && chmod "g+rwX" /work \ && chown 1001:root /work COPY --chown=1001:root target/*-runner /work/application EXPOSE 8080 USER 1001 CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
-
Save and close
src/main/docker/Dockerfile.native
-
-
Building a native image can be accomplished by running
./mvnw package -Pnative -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true -Dquarkus.container-image.group=
in the terminal. Building a native image may take several minutes to complete depending on the specs of your machine and how much CPU/RAM is available.There are many container image options available. The
quarkus.container-image.group=
option removes the${user.name}
from the final image name. If we did not include this option, the final image would be created as${user.name}/${quarkus.application.name}:${quarkus.application.version}
. This simply makes it easier to write this tutorial without having to worry about people's usernames!NOTE: If the native image build fails due to an out of memory error, you may need to increase the memory size of your docker daemon to a minimum of 6GB.
You could also try adding the parameter
-Dquarkus.native.additional-build-args=-J-XX:TieredStopAtLevel=1
to the./mvnw package
command you ran. -
Once the native image build is complete, start the PostgreSQL database container needed by the application:
docker run -it --rm --name tododb -e POSTGRES_USER=todo -e POSTGRES_PASSWORD=todo -e POSTGRES_DB=tododb -p 5432:5432 postgres:14
Quarkus Dev Services is only available in development mode. Running a native executable runs in production mode.
-
Before starting the native image container, we first need to get the internal ip address of the running PostgreSQL DB so that our Quarkus application can connect to it.
-
In another terminal, run
docker inspect tododb | grep IPAddress
. You should see something like"SecondaryIPAddresses": null, "IPAddress": "172.17.0.2", "IPAddress": "172.17.0.2",
In this example, the ip address is
172.17.0.2
.
-
-
Now run the native executable image, making sure to substitute the ip address gathered in the previous step
docker run -i --rm -p 8080:8080 -e QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://172.17.0.2:5432/tododb -e QUARKUS_DATASOURCE_USERNAME=todo -e QUARKUS_DATASOURCE_PASSWORD=todo spring-to-quarkus-todo:0.0.1-SNAPSHOT
If this command didn't work, make sure you substituted the ip address you gathered in step 5 in the command!
Notice the startup time. It should start up in only a few milliseconds!
- Return to your browser to http://localhost:8080
- Everything should work as before! No hassle native image generation!
- Close both the application and the PostgreSQL instances via
CTRL-C
when you're done.