Skip to content

Commit f7b3248

Browse files
authored
Merge pull request #1856 from cescoffier/virtual-thread-containers
Virtual threads - blog post 6
2 parents 12efd19 + c325206 commit f7b3248

File tree

2 files changed

+139
-3
lines changed

2 files changed

+139
-3
lines changed

Diff for: _posts/2023-09-19-virtual-thread-1.adoc

+1-3
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,7 @@ Next, we will cover:
359359
- https://quarkus.io/blog/virtual-threads-3/[How to test virtual threads applications]
360360
- https://quarkus.io/blog/virtual-threads-4/[How to process Kafka messages using virtual threads]
361361
- https://quarkus.io/blog/virtual-threads-5/[How to build a native executable when using virtual threads]
362-
- How to containerize an application using virtual threads (in JVM mode) (_to be published_)
363-
- How to containerize an application using virtual threads in native mode (_to be published_)
364-
- How to process Kafka messages using virtual threads (_to be published_)
362+
- https://quarkus.io/blog/virtual-threads-6/[How to containerize an application using virtual threads]
365363
- What are we exploring to improve the virtual thread support in Quarkus (_to be published_)
366364

367365
To know more about the virtual thread support in Quarkus, check the https://quarkus.io/guides/virtual-threads[Virtual thread reference guide].

Diff for: _posts/2023-12-14-virtual-threads-6.adoc

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
layout: post
3+
title: 'Containerizing virtual thread applications'
4+
date: 2023-12-14
5+
tags: virtual-threads native
6+
synopsis: 'Learn how to containerized applications using virtual threads.'
7+
author: cescoffier
8+
---
9+
:imagesdir: /assets/images/posts/virtual-threads
10+
11+
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.
12+
This post continues from that point, explaining how to containerize the application.
13+
Containerization involves packaging the application into a container image, and we'll use the `quarkus-container-image-jib` extension for this purpose.
14+
Quarkus offers other extensions for containerization, such as `quarkus-container-image-docker`, so choose the one that suits your preference.
15+
16+
Packaging an application using virtual threads is not different from packaging a regular application.
17+
Quarkus hides all the complexity, selecting the right base image and configuring the native image build process to use the right flags.
18+
19+
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].
20+
21+
22+
== Adding Jib to the Project
23+
24+
First, add the `quarkus-container-image-jib` extension to the project:
25+
26+
[source, xml]
27+
----
28+
<dependency>
29+
<groupId>io.quarkus</groupId>
30+
<artifactId>quarkus-container-image-jib</artifactId>
31+
</dependency>
32+
----
33+
34+
Next, open the `application.properties` file and add the following properties:
35+
36+
[source, properties]
37+
----
38+
quarkus.container-image.build=true # <1>
39+
quarkus.container-image.name=virtual-threads-demos-${quarkus.application.name} # <2>
40+
----
41+
1. Enable container image build; every `mvn package` run will build a container image.
42+
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.
43+
44+
== Building the Container Image for the JVM
45+
46+
To create the container image for the Java application, run the following command:
47+
48+
[source, bash]
49+
----
50+
$ mvn clean package
51+
----
52+
53+
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.
54+
This image is automatically selected by Quarkus as the project uses Java 21.
55+
56+
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.
57+
58+
You can run the container image with:
59+
60+
[source, bash]
61+
----
62+
$ docker run -it \
63+
-p8080:8080 \
64+
-e QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://docker.for.mac.localhost/rest-crud \
65+
clement/virtual-threads-demos-crud-example:1.0.0-SNAPSHOT
66+
----
67+
68+
Ensure to replace `clement` with your username.
69+
70+
NOTE: If you are running on ARM64, you may encounter a warning regarding the image's platform mismatch.
71+
You can override this using: `$ mvn clean package -DskipTests -Dquarkus.jib.platforms=linuxarm64`.
72+
73+
== Building the Container Image for the Native Executable
74+
75+
To build the container image for the native executable, use the following command:
76+
77+
[source, bash]
78+
----
79+
$ mvn package -DskipTests \
80+
-Dnative \
81+
-Dquarkus.native.container-build=true \
82+
-Dquarkus.jib.platforms=linux/arm64
83+
----
84+
85+
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`).
86+
87+
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.
88+
89+
Run the container image with:
90+
91+
[source, bash]
92+
----
93+
$ docker run -it \
94+
-p8080:8080 \
95+
-e QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://docker.for.mac.localhost/rest-crud \
96+
clement/virtual-threads-demos-crud-example:1.0.0-SNAPSHOT
97+
----
98+
99+
Use the same configuration trick for the database connection, and replace `clement` with your username.
100+
101+
== Pushing the Container Image
102+
103+
Quarkus can push the container image to a registry.
104+
To push to the GitHub container repository, use these properties:
105+
106+
[source, properties]
107+
----
108+
quarkus.container-image.registry=ghcr.io
109+
quarkus.container-image.group=cescoffier
110+
quarkus.container-image.username=cescoffier
111+
quarkus.container-image.password=${GITHUB_TOKEN}
112+
----
113+
114+
The `GITHUB_TOKEN` environment variable configures the GitHub token, which must have permission to create packages. Push the container image using:
115+
116+
[source, bash]
117+
----
118+
$ mvn clean package -DskipTests -Dquarkus.container-image.push=true
119+
----
120+
121+
Append `-Dnative` for native images.
122+
123+
Multi-architecture container images can be created using:
124+
125+
[source, bash]
126+
----
127+
$ mvn clean package -DskipTests -Dquarkus.container-image.push=true -Dquarkus.jib.platforms=linux/amd64,linux/arm64
128+
----
129+
130+
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.
131+
132+
== Summary
133+
134+
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.
135+
136+
Attentive readers would have seen that nothing is different from a regular application.
137+
Quarkus handles all the complexity, selecting the right base image and configuring the native image build process to use the right flags.
138+

0 commit comments

Comments
 (0)