Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Managing Java containers with Quarkus and Podman Desktop

July 3, 2023
Kevin Dubois
Related topics:
ContainersJavaKubernetesQuarkus
Related products:
Podman DesktopRed Hat build of Quarkus

Share:

    The world of software development is changing quickly, and it is no different for the Java developer who needs to learn new skills to manage Java containers.

    In the traditional Java development world, it was rather typical to build a Java artifact (whether it be a .jar, .war, or .ear), and "throw it over the wall" for the middleware and operations people to take care of. It kind of made sense, too, because configuring and running enterprise application servers was not always that easy, and in the end, the developer's laptop would probably not match the specs of staging or production environments so that the configuration would be different anyway. We all know the "It works on my machine" cliché, after all.

    These days, things need faster and better delivery, and production issues often require resolution in a very timely manner because every second of downtime could potentially cause revenue loss for an organization. New ways of delivering applications have been conceived—and with it, cloud-native applications, containers, and DevOps—and the "but it worked on my machine" excuse is no longer valid.

    Java developers need to be able to work with containers because it is a practical way to test applications in a production-like environment on their local machine. Some developers and organizations choose to take development off the local machine and right into the cloud with the IDE itself running in a reproducible, containerized environment for even greater consistency. Red Hat OpenShift Dev Spaces is one way you can do this, but it is out of the scope of this article.

    Building containers with Java

    Building and managing containers can become overwhelming rather quickly for the Java developer, though. At the face of it, it's "just" a matter of creating a Dockerfile with instructions to copy the artifact into a base image and doing a Docker build. However, in reality, creating a container image from an application requires many more considerations than that.

    Choosing a base image

    To start with, you will need a base image: do you start from scratch, adding every dependency individually, or use a base image that already has a Java Virtual Machine (JVM) implementation included? Or maybe you've opted to do a native build of the application and don't need a JVM running in your container. Either way, you will need to find a trusted source that provides tested, secured, ideally signed, Open Container Initiative (OCI)-compliant, and stable images for the particular Java version you are targeting. And hopefully, this source can provide support and maintain and backport patches going forward. The base image will likely need tuning as well to optimize performance, not something every developer is familiar with.

    Red Hat's Universal Base Images (UBI) are a good starting point for building container images. UBIs are free to use, and they are at the core a subset of the Red Hat Linux (RHEL) distribution, providing a stable, secure, optimized and reliable base for building containers. There are several JVM-based UBI images available, as well as micro UBIs for deploying native binaries.

    Building the container image

    Once you have decided on a base image, you will need a way to build the container image. The best-known way is to create a Dockerfile (or Containerfile as the more agnostic way of naming such a file) and then build it with Docker.

    This is certainly not the only way to build containers, though. You can use the same Containerfile to build an image with Podman, a fully open source container engine with actually quite a few more features than the Docker engine. You could also use Buildah, another open source tool specifically created for building container images.

    There are alternative ways of building containers without needing a Containerfile. There are build tools such as Source2Image (S2I), Buildpacks, Jib, and many more. These vary in complexity, but each one aims to streamline the container build process, particularly for developers.

    Jib, for example, is a build tool specifically created for building container images with Java. S2I is a tool that take can take source code, do an introspection to see what kind of application it is (e.g., the presence of a pom.xml would indicate that it is a Java application), and then build a container image from the application's source code using build images that are predefined by the S2I tool, or custom build images provided by the user. Buildpacks work similarly but require a buildpack builder image.

    The downside is that you will need to install a specific command line interface (CLI) program for each of these container build tools and understand how to use them. Moreover, you will need to know what base images these build tools use (if applicable) or supply your own and figure out whether they are safe to use.

    For further information on container terminology, Scott McCarty wrote a comprehensive introduction in this article.

    How Quarkus helps with Containerfiles

    Quarkus is a Java stack that aims to make cloud-native development easier for the Java developer. Quarkus will supply Containerfiles from the moment the developer bootstraps a Quarkus application, whether it is through the Quarkus CLI's command quarkus create app, by generating a starter project on code.quarkus.io, or by using one of the Quarkus plug-ins in VS Code or IntelliJ.

    By bootstrapping a new Quarkus application, a folder is created in src/main/docker with prebaked Containerfiles (named Dockerfile.* in this case) based on the UBI images previously mentioned in this article (Figure 1).

    Dockerfiles supplied by Quarkus upon bootstrapping an application
    Figure 1: Dockerfiles supplied by Quarkus upon bootstrapping an application.

    Quarkus supplies 4 different Containerfiles for different use cases:

    • Dockerfile.jvm is used by default to build a Java container that runs the Quarkus application in JVM mode.
    • Dockerfile.legacy-jar is used if for the legacy-jar packaging type (more information on legacy vs fast-jar in Quarkus).
    • Dockerfile.native uses a UBI without JVM for running natively compiled Quarkus apps.
    • Dockerfile.native-micro is a custom built micro UBI image to run native Quarkus apps.

    These Containerfiles can be used with regular Docker or Podman commands, but Quarkus also enables building container images directly from build tools such as Maven or Gradle. Basically, you can build an image with, for example, mvn package quarkus:image-build and Quarkus will automatically build a container image using, by default, the Dockerfile.jvm that came with the Quarkus project.

    Similarly, to build an image without a JVM that runs a natively compiled binary, one must simply add the --Dnative parameter to the command (in this case, Maven) , e.g., mvn package quarkus:image-build -Dnative.

    There's one caveat with the latter command. You will need to install the GraalVM Native Image Builder executable (called native-image). Quarkus, however, has an alternative way to leverage GraalVM's Native Image Build without installing the native-image executable locally. Quarkus will, in fact, detect the absence of the native-image executable and attempt to download a container image that contains the bits to do a native Java compilation and actually build the native binary in a container (provided you have Docker or Podman installed, of course). The native binary builder image is based on Mandrel, a downstream distribution of the GraalVM community edition whose main goal is to provide a native-image release specifically to support Quarkus.

    More CLI magic with Quarkus

    The Quarkus CLI is, in essence, a convenience wrapper around the Maven or Gradle build tools that let you create projects, start Quarkus in dev and test mode, manage extensions and do essential build, dev, and even deploy. It provides a way to control the full inner-loop development experience without having to switch tools.

    Thanks to the Quarkus CLI, you can execute simple commands that are easy to remember, such as quarkus image build. Behind the scenes, Quarkus will invoke the chosen build tool, package the application, and build a container image using the previously mentioned Containerfiles and a local Docker or Podman instance (as shown in Figure 2).

    Similarly, to use either Jib or Buildpacks, you can run the same command and append the container build tool of your preference, e.g., quarkus image build jib, or quarkus image build buildpack.

    Quarkus container image build success message
    Figure 2: Image build success message after running quarkus image build.

    The Quarkus CLI lets you push a container image to a registry as well with quarkus image push. In fact, the application build, container build, and container push can be done in one go by adding the --also-build flag, e.g., quarkus image push --also-build. Or, as a natively compiled binary, quarkus image push --also-build --native.

    Managing and running your container with Podman Desktop

    Once the container image has been built, you will likely want to run the container to make sure it actually works, or perhaps to use it with other applications. You could learn how to use Podman or Docker commands such as podman run or docker run; however, you will need to have at least some expertise in these tools to expose ports, mount volumes, execute commands, etc.

    Podman Desktop is a UI tool that makes running and managing containers much easier with an intuitive user experience. You can install it on Windows (with WSL), macOS, and Linux, and it will install the underlying Podman utility as well, if needed.

    You can spin up a container from the images view by clicking the play button next to the container image, as shown in Figure 2. You can then customize the container runtime configuration or let Podman automatically map the container's external port to the app's internal port based on the EXPOSE value of the image (by default, 8080 in Quarkus). Podman can automatically figure out if another process on the machine is already using that port and reassign the container's external port to use a different one instead. This is an impressive feature, in contrast to having to manually figure out if a port is being used on your machine with a command such as netstat or lsof, which is typically more in the realm of a system administrator.

    Podman Desktop Images view with the cursor hovering over the start container button
    Figure 3: Podman Desktop's Images view with "play" button to start a container.

    More Podman Desktop features

    Podman Desktop can do more than just run containers. For example, you might want to ssh into a container to do debugging or access or even modify settings. Using the CLI, you would have to find out the name of your container (e.g., with podman ps) and then remember a command like podman exec -it CONTAINER_ID /bin/bash. With Podman Desktop, it's as simple as selecting the container in the container view and clicking the Terminal tab.

    Podman Desktop showing the container terminal view
    Figure 4: Executing commands in a terminal inside a container with Podman Desktop.

    Similarly, if you want to access the logs of a container, you can click the Logs tab, or if you want to inspect the state of a container—e.g., to see what file systems it's using, what environment variables are set, etc.—then you could just click Inspect.

    Using pods outside of Kubernetes

    Podman Desktop, as its name implies, can also run containers as pods. You could, for example, run another container, such as a caching database (Redis or Infinispan), and combine it with the application's container into a pod resulting in a single deployable and scalable unit that shares networking, just like one would run a pod on Kubernetes.

     Kubernetes and Podman Desktop

    It is possible to deploy containers or pods from Podman Desktop directly to a Kubernetes instance as well (Figure 3). To do so, simply click the rocket icon in the top right of the Podman Desktop view. Podman Desktop will detect a Kubernetes context (provided you are logged in to a Kubernetes cluster using, e.g., kubectl login) and proceed to deploy the container(s) on a cluster as pods.

    Podman Desktop showing the deploy to kubernetes button
    Figure 5: Podman Desktop's Logs view, with the Deploy to Kubernetes button highlighted.

    If a Kubernetes cluster is unavailable, Podman Desktop can start a Kubernetes-in-Docker (Kind) cluster through the Kind extension, available in the Podman Desktop settings.

    Another alternative is to create a no-cost Developer Sandbox for Red Hat OpenShift instance. You can provision one by visiting developers.redhat.com/developer-sandbox and following the Create a free OpenShift Sandbox instance. This gives you a fully functional Kubernetes instance you can use to deploy your containerized application(s) to, and perhaps even expose the application to the world with!

    Get started today

    Building and running Java containers has become much easier over the years. Using frameworks such as Quarkus and tools like Podman Desktop and OpenShift make it simple to start working with containers, even for Java developers who have are new to the cloud-native world.

    Try it today by creating a Quarkus application, building it into a container image, and running it on Podman Desktop. 

    Additional resources

    • What is Podman Desktop? A developer's introduction
    • Podman Desktop 1.0: Local container development made easy
    • Tutorial: Deploy and test Kubernetes containers using Podman Desktop
    • Kubernetes-native inner loop development with Quarkus
    • Learn Quarkus faster in the Developer Sandbox for Red Hat OpenShift
    • Build your first Java serverless function using a Quarkus quick start
    • Quarkus for Spring developers: Kubernetes-native design patterns
    Last updated: January 29, 2024

    Related Posts

    • Deploy and test Kubernetes containers using Podman Desktop

    • What is Podman Desktop? A developer's introduction

    • Podman Desktop 1.0: Local container development made easy

    • Cloud-native Java applications made easy: Eclipse JKube 1.0.0 now available

    • Quarkus, a Kubernetes-native Java runtime, now fully supported by Red Hat

    Recent Posts

    • How to run AI models in cloud development environments

    • How Trilio secures OpenShift virtual machines and containers

    • How to implement observability with Node.js and Llama Stack

    • How to encrypt RHEL images for Azure confidential VMs

    • How to manage RHEL virtual machines with Podman Desktop

    What’s up next?

    java-nutshell-cover_Share

    Read Java in a Nutshell, the reference guide every Java developer needs at their fingertips. It’s designed to help you get the most out of versions through Java 17, with examples that show how to take advantage of modern Java APIs and development best practices.

    Get the e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue