This is a cache of https://developer.ibm.com/tutorials/quarkus-basics-06/. It is a snapshot of the page as it appeared on 2025-12-05T02:53:45.354+0000.
Containerizing Quarkus applications and deploying them with Kubernetes - IBM Developer
In this tutorial, you will package a simple Quarkus application into a container image and deploy it to Kubernetes. You don’t need to write Kubernetes YAML by hand, Quarkus can generate the manifests for you during the build. By using Quarkus to help package your app, the developer experience is smooth and consistent with the Quarkus philosophy of convention over configuration.
Containers and Quarkus
In the cloud, applications run in containers. Containers package everything an app needs, code, runtime, and libraries, into one portable unit. Quarkus applications are small and fast, which makes them ideal for containerized environments like Kubernetes and OpenShift.
Quarkus supports multiple container build strategies, so you can choose the one that works best for your team:
Jib: A Maven or Gradle plugin that builds container images without a Dockerfile. Great for CI/CD pipelines.
Dockerfile or Podmanfile: The traditional way where you write a file and build with docker build or podman build.
-Quarkus container-image extension: Lets you build images directly with ./mvnw package -Dquarkus.container-image.build=true.
Buildpacks: Uses Cloud Native Buildpacks to create images without Dockerfiles.
For this tutorial, we’ll use Jib. The extension quarkus-container-image-jib is powered by Jib for performing container image builds. The major benefit of using Jib with Quarkus is that all the dependencies (everything found under target/lib) are cached in a different layer than the actual application making rebuilds really fast and small (when it comes to pushing). Another important benefit of using this extension is that it can create a container image without having to have any dedicated client side tooling (like Docker) or running daemon processes (like the Docker daemon) when all that is needed is the ability to push to a container image registry.
Step 1. Set up a new Quarkus project
Before you begin, make sure that you have this software:
JDK 17+ (Quarkus 3 requires at least Java 17)
Apache Maven 3.8.1+
A container runtime such as Podman or Docker
An IDE like IntelliJ, VS Code, or Eclipse
Generate a new Quarkus project with the Jib extension:
Quarkus is built around extensions. Instead of writing custom Dockerfiles or YAML, you can add extensions that handle container images and Kubernetes integration for you. This is part of Quarkus’s philosophy: let the framework do the heavy lifting so you can focus on your code.
For this step, we need two new extensions:
container-image-jib. This extension builds container images by using Jib, a Java tool that creates images directly from your project. You don’t need Docker or Podman installed for this. Jib takes your compiled application and builds a layered container image. This makes rebuilding faster and keeps your images small.
kubernetes. This extension generates Kubernetes manifests for you. When you build your project, Quarkus automatically creates a Deployment and a Service in target/kubernetes/. This saves you from writing YAML by hand and ensures that the manifests are consistent with your application’s configuration.
You can also add both to an existing Quarkus project with the Quarkus CLI:
With them in place, your project knows how to build an image and describe how that image should run inside Kubernetes.
Step 2. Configure the container image
By default, Quarkus will build a container image with a generic name. But in real projects, images need to have meaningful names and versions. This is especially true when you push them to a container registry (like Quay.io or Docker Hub) so that Kubernetes can pull them later.
Quarkus uses three simple properties to define the image:
quarkus.container-image.group which is usually your container registry username or organization.
quarkus.container-image.name which is the application name, often the same as your project.
quarkus.container-image.tag which is the version, which helps you keep track of releases.
Add these to src/main/resources/application.properties:
Replace myuser with your user name from your container registry.
When you run the build later, Quarkus will use this information to create an image named:
myuser/getting-started:1.0.0
Copy codeCopied!
This naming convention is important because it allows Kubernetes to find and run the correct version of your application.
Step 3. Build the container image
Building a container image is more than just packaging your code. The image is what Kubernetes (or any container runtime) runs. Quarkus integrates tightly with Jib to build efficient images. Jib doesn’t just create a single “big file.” Instead, it builds layered images. This means:
One layer contains your application dependencies (all JAR files your app uses).
Another layer contains your compiled classes.
Another layer contains your configuration and resources.
Why is this important? If you only change your code but not your dependencies, Jib can reuse the dependency layer from a previous build. That makes rebuilding much faster and keeps images smaller. This layering is one reason Quarkus builds feel lightweight compared to traditional Java apps.
Use Jib to assemble the container image with layers.
Tag the image with the values from application.properties.
Generate Kubernetes manifests in target/kubernetes/.
List your local images:
podman images
Copy codeCopied!
If you don’t use Podman locally, Jib might have pushed directly to your container registry (if configured).
You can also inspect the generated Kubernetes manifest:
ls target/kubernetes/
Copy codeCopied!
You should see:
kubernetes.yml
This file contains a Deployment and a Service that describe how your Quarkus app runs in Kubernetes.
By building images this way, you get reproducible, optimized containers without writing Dockerfiles. Jib ensures that your builds are fast, efficient, and friendly to CI/CD pipelines.
Step 4. Deploy your app to Kubernetes
In this particular tutorial, we are just going to show you how to deploy to Kubernetes but we assume that you have access to Kubernetes. If not, you can try minikube locally (for example, with Podman Desktop) or experiment with the OpenShift Developer Sandbox.
Building a container image is only half the story. To actually run your application in Kubernetes, you need to describe how it should run. Kubernetes uses YAML manifests to define resources like:
Deployment: Tells Kubernetes how to run your application. It defines the container image, how many replicas (copies) you want, and restart policies. If a pod crashes, the Deployment ensures a new one is started.
Service: Exposes your application inside the cluster (and sometimes outside). A Service gives your pods a stable network name and load balances traffic across replicas.
And this is exactly what was generated in the kubernetes.yml by Quarkus. Based on your configuration. You didn’t have to touch a single line of configuration or be worried about syntax or missing fields. Quarkus ensures your Deployment and Service match your application configuration.
You should see your Quarkus app running inside Kubernetes.
Quarkus automates one of the most painful steps of cloud deployment. Instead of spending hours writing YAML, you focus on your application code. The generated manifests follow Kubernetes best practices, so you get a solid starting point without manual effort.
You’ve seen how Quarkus generates Kubernetes resources for you. As your applications grow, you can explore more advanced features, such as:
Customizing the generated manifests with extra labels or annotations.
Integrating with OpenShift by using the quarkus-openshift extension.
Automatically pushing images to registries with -Dquarkus.container-image.push=true.
You learned how Quarkus simplifies containerization by using Jib to build layered container images without Dockerfiles, and how the Kubernetes extension automatically generates Deployment and Service manifests based on your application configuration. This convention-over-configuration approach eliminates the need to write YAML manually and ensures that your containerized applications are optimized for Kubernetes deployments with minimal effort.
About cookies on this siteOur websites require some cookies to function properly (required). In addition, other cookies may be used with your consent to analyze site usage, improve the user experience and for advertising.For more information, please review your cookie preferences options. By visiting our website, you agree to our processing of information as described in IBM’sprivacy statement. To provide a smooth navigation, your cookie preferences will be shared across the IBM web domains listed here.