From c325206cbd128212f1740ef149b32087ff557696 Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Mon, 11 Dec 2023 10:53:04 +0100 Subject: [PATCH] Virtual threads - blog post 6 --- _posts/2023-09-19-virtual-thread-1.adoc | 4 +- _posts/2023-12-14-virtual-threads-6.adoc | 138 +++++++++++++++++++++++ 2 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 _posts/2023-12-14-virtual-threads-6.adoc diff --git a/_posts/2023-09-19-virtual-thread-1.adoc b/_posts/2023-09-19-virtual-thread-1.adoc index b8008b487d..bc1bfcf9b8 100644 --- a/_posts/2023-09-19-virtual-thread-1.adoc +++ b/_posts/2023-09-19-virtual-thread-1.adoc @@ -359,9 +359,7 @@ Next, we will cover: - https://quarkus.io/blog/virtual-threads-3/[How to test virtual threads applications] - https://quarkus.io/blog/virtual-threads-4/[How to process Kafka messages using virtual threads] - https://quarkus.io/blog/virtual-threads-5/[How to build a native executable when using virtual threads] -- How to containerize an application using virtual threads (in JVM mode) (_to be published_) -- How to containerize an application using virtual threads in native mode (_to be published_) -- How to process Kafka messages using virtual threads (_to be published_) +- https://quarkus.io/blog/virtual-threads-6/[How to containerize an application using virtual threads] - What are we exploring to improve the virtual thread support in Quarkus (_to be published_) To know more about the virtual thread support in Quarkus, check the https://quarkus.io/guides/virtual-threads[Virtual thread reference guide]. diff --git a/_posts/2023-12-14-virtual-threads-6.adoc b/_posts/2023-12-14-virtual-threads-6.adoc new file mode 100644 index 0000000000..f2c952f76f --- /dev/null +++ b/_posts/2023-12-14-virtual-threads-6.adoc @@ -0,0 +1,138 @@ +--- +layout: post +title: 'Containerizing virtual thread applications' +date: 2023-12-14 +tags: virtual-threads native +synopsis: 'Learn how to containerized applications using virtual threads.' +author: cescoffier +--- +:imagesdir: /assets/images/posts/virtual-threads + +In another https://quarkus.io/blog/virtual-threads-2/[blog post], we explored how to implement a CRUD application with Quarkus to harness the power of virtual threads. +This post continues from that point, explaining how to containerize the application. +Containerization involves packaging the application into a container image, and we'll use the `quarkus-container-image-jib` extension for this purpose. +Quarkus offers other extensions for containerization, such as `quarkus-container-image-docker`, so choose the one that suits your preference. + +Packaging an application using virtual threads is not different from packaging a regular application. +Quarkus hides all the complexity, selecting the right base image and configuring the native image build process to use the right flags. + +The full code for this blog post is available in the `crud-example` directory of the https://github.com/quarkusio/virtual-threads-demos[virtual-threads-demos GitHub repository]. + + +== Adding Jib to the Project + +First, add the `quarkus-container-image-jib` extension to the project: + +[source, xml] +---- + + io.quarkus + quarkus-container-image-jib + +---- + +Next, open the `application.properties` file and add the following properties: + +[source, properties] +---- +quarkus.container-image.build=true # <1> +quarkus.container-image.name=virtual-threads-demos-${quarkus.application.name} # <2> +---- +1. Enable container image build; every `mvn package` run will build a container image. +2. Define the name of the container image. The `${quarkus.application.name}` placeholder is replaced by the application name, which is `crud-example` in our case. + +== Building the Container Image for the JVM + +To create the container image for the Java application, run the following command: + +[source, bash] +---- +$ mvn clean package +---- + +The logs will show the container image build process, with the image being built using the `registry.access.redhat.com/ubi8/openjdk-21-runtime:1.18` base image. +This image is automatically selected by Quarkus as the project uses Java 21. + +Take note of the resulting image name: `clement/virtual-threads-demos-crud-example:1.0.0-SNAPSHOT`. The first part is your username by default, do do not forget to change it in the other commands. + +You can run the container image with: + +[source, bash] +---- +$ docker run -it \ + -p8080:8080 \ + -e QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://docker.for.mac.localhost/rest-crud \ + clement/virtual-threads-demos-crud-example:1.0.0-SNAPSHOT +---- + +Ensure to replace `clement` with your username. + +NOTE: If you are running on ARM64, you may encounter a warning regarding the image's platform mismatch. +You can override this using: `$ mvn clean package -DskipTests -Dquarkus.jib.platforms=linuxarm64`. + +== Building the Container Image for the Native Executable + +To build the container image for the native executable, use the following command: + +[source, bash] +---- +$ mvn package -DskipTests \ + -Dnative \ + -Dquarkus.native.container-build=true \ + -Dquarkus.jib.platforms=linux/arm64 +---- + +The `-Dnative` flag enables native compilation, and `-Dquarkus.jib.platforms=linux/arm64` specifies the target platform (required if you are on ARM64, as by default it will pick `linux/amd64`). + +Note the property `quarkus.native.container-build=true`, which instructs Quarkus to use a container image to build the native executable, avoiding the need for GraalVM installation. + +Run the container image with: + +[source, bash] +---- +$ docker run -it \ + -p8080:8080 \ + -e QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://docker.for.mac.localhost/rest-crud \ + clement/virtual-threads-demos-crud-example:1.0.0-SNAPSHOT +---- + +Use the same configuration trick for the database connection, and replace `clement` with your username. + +== Pushing the Container Image + +Quarkus can push the container image to a registry. +To push to the GitHub container repository, use these properties: + +[source, properties] +---- +quarkus.container-image.registry=ghcr.io +quarkus.container-image.group=cescoffier +quarkus.container-image.username=cescoffier +quarkus.container-image.password=${GITHUB_TOKEN} +---- + +The `GITHUB_TOKEN` environment variable configures the GitHub token, which must have permission to create packages. Push the container image using: + +[source, bash] +---- +$ mvn clean package -DskipTests -Dquarkus.container-image.push=true +---- + +Append `-Dnative` for native images. + +Multi-architecture container images can be created using: + +[source, bash] +---- +$ mvn clean package -DskipTests -Dquarkus.container-image.push=true -Dquarkus.jib.platforms=linux/amd64,linux/arm64 +---- + +This option is not applicable for native executables, howver, it is very convenient for JVM applications as you can then use the same container image on different platforms. + +== Summary + +This blog post demonstrated how to containerize a virtual thread application using Quarkus and the Jib container image extension. Both JVM applications and native executables were covered. + +Attentive readers would have seen that nothing is different from a regular application. +Quarkus handles all the complexity, selecting the right base image and configuring the native image build process to use the right flags. +