Building and Running Quarkus(Supersonic Subatomic Java) application native image in docker container using PODMAN

Dhritiman Sana
5 min readFeb 25, 2021

Target audience

This article is targeted towards developers, architects and managers that look for additional information on Podman and how to setup podman in Ubuntu and high level uses of Podman. Article also demonstrate how to create a docker image using quarkus native and run the container and emphasize on the amazing fast(supersonic) boot time of the Quarkus application.

Quick Intro for Podman and Quarkus

Quarkus is a Kubernetes Native Java framework tailored for GraalVM and HotSpot, crafted from best-of-breed Java libraries and standards. The goal of Quarkus is to make Java a leading platform in Kubernetes and serverless environments while offering developers a unified reactive and imperative programming model to optimally address a wider range of distributed application architectures. Quarkus provides Amazingly fast boot time, incredibly low RSS memory (not just heap size!) offering near instant scale up and high-density memory utilization in container orchestration platforms like Kubernetes. Quarkus provides live reloading f the code and developers don’t need to restart servers once they change the code .

Podman offer experience similar to docker command line however it don’t need to have daemon processes like docker daemon. Podman and docker images are compatible. Also, podman can run as non-root user however docker always needs root as user. In summary Podman similar with Docker CLI however it has more benefits over Docker CLIs

What we will be doing here

In the below exercise we will see using podman how to build a native docker image from a quarkus application and then run the docker image.

A simple rest application built using quarkus can be started in approx .1 sec in native mode and please refer below picture for details . In this exercise we will highlight on the amazing fast(supersonic) boot time of the quarkus application.

Boot Time for Quarkus application

Lets start hands on

Step 1: Install podman in Ubuntu 20.04.1 LTS. Execute the below commands

echo “deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /” | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list

curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/Release.key | sudo apt-key add -

sudo apt-get update

sudo apt-get -y upgrade

sudo apt-get -y install podman

Step 2: Clone a Quarkus Repository in Local

$ git clone https://github.com/dhrsana1/quarkus_rest_app.git

Step 3: Use podman to build the project using dockerfile

Cd to the directory where the repository is cloned

Cd /quarkus_rest_app

Run the below podman command to build the docker images

podman build -t quarkusdemo .

Results of the command — here the images was build already earlier.

STEP 1: FROM quay.io/quarkus/centos-quarkus-maven:20.2.0-java11 AS build

STEP 2: COPY pom.xml /usr/src/app/

→ Using cache 8d180abf5f5403a76a439d06ef3a04b4fa78cf7482864ff10266d64ca2e41c35

→ 8d180abf5f5

STEP 3: RUN mvn -f /usr/src/app/pom.xml -B de.qaware.maven:go-offline-maven-plugin:1.2.5:resolve-dependencies

→ Using cache 4f4bf51381148d4b0ce04c8f85c918238c43c3706d820f640381b190f5b27740

→ 4f4bf513811

STEP 4: COPY src /usr/src/app/src

→ Using cache 0ee311002a8dd6f74d74337a8f9041afaedb857193f5d03066c9b58236ba260c

→ 0ee311002a8

STEP 5: USER root

→ Using cache dae89d8530dc6f569ca86782d4640263010322cdcf99d9f29691f45c91425302

→ dae89d8530d

STEP 6: RUN chown -R quarkus /usr/src/app

→ Using cache 0fe14ee87695092a793a16706b8893525301eba156b7cc9416ee9ccb3f004a1b

→ 0fe14ee8769

STEP 7: USER quarkus

→ Using cache 7b63bb9aefce30c11d9c83eb3d733e9fb015a73dfeeda462c8477ce52b30a1d7

→ 7b63bb9aefc

STEP 8: RUN mvn -f /usr/src/app/pom.xml -Pnative clean package

→ Using cache 3bc5a7c86c772c636b6cb055ff17e7f8c8ed38bda249774e0b53a4a7cd4af53a

→ 3bc5a7c86c7

STEP 9: FROM registry.access.redhat.com/ubi8/ubi-minimal

STEP 10: WORKDIR /work/

→ Using cache 70d8aa7009c8d398df22f4f9e2c67fe6ff259d994fb520d142eda5e7827f9a3b

→ 70d8aa7009c

STEP 11: COPY — from=build /usr/src/app/target/*-runner /work/application

→ Using cache 71480365d6c544d4be31379bb19056ae19ed5303032bbba665232d4359681e25

→ 71480365d6c

STEP 12: RUN chmod 775 /work /work/application && chown -R 1001 /work && chmod -R “g+rwX” /work && chown -R 1001:root /work

→ Using cache c83e23c2eec36b96a11234ac3cb113500cc79a3679a14136bac9b495d1afc6aa

→ c83e23c2eec

STEP 13: EXPOSE 8080

→ Using cache b20e2a8b1e2f341f319841ce4a7ca0f8f1aedc6b410ed773449801084bd2ecae

→ b20e2a8b1e2

STEP 14: USER 1001

→ Using cache f348c2835e9fdd427144fa73e4ad52a25c57a7c6cf42723f2f7c7126ad47cb43

→ f348c2835e9

STEP 15: CMD [“./application”, “-Dquarkus.http.host=0.0.0.0”]

→ Using cache e6aed77523d6453d11aaa6d45f417b72fd2c7ed6eedf17edeff6f878fbda3dd9

STEP 16: COMMIT quarkusdemo

→ e6aed77523d

e6aed77523d6453d11aaa6d45f417b72fd2c7ed6eedf17edeff6f878fbda3dd9

Step 4: List all podman images

Podman Images

Step 5: Running images using podman

podman run -p 8080:8080 quarkusdemo

Running containers in podman

Step 6: Curl the rest end point of native quarkus application

You can see the response coming from the quarkus application — rest end point

Quarkus app Rest response

Step7: You will notice that the native image started in approximately .1 second

Conclusion

As you see in the above example podman command lets you run containers as standalone entities, without requiring that Kubernetes, the Docker runtime, or any other container runtime be involved. It is a tool that can act as a replacement for the docker command, implementing the same command-line syntax, while it adds even more container management features. Quarkus uses Ahead of Time compilation strategy while building the application, which gives the benefit to loading only the necessary classes which helps to start the application. Here in this example we can see Quarkus apps can be compiled down to a native executable, for even greater efficiency using GrallVM and the native build . Using Mandrel (a downstream distribution of GraalVM), the quarkus application is analyzed to find “dead code” (code paths which will never be visited at runtime) and eliminate this from the application executable. This results in tiny and lightweight runnable applications that start up in tens of milliseconds, and require tens of megabytes of memory at runtime.

References
https://quarkus.io/
https://podman.io/
https://developers.redhat.com/

--

--