Containerize a Spring Boot application with Podman Desktop

FONT: https://developers.redhat.com/articles/2023/10/19/containerize-spring-boot-application-podman-desktop#running_the_containerized_application

You are here

Containerize a Spring Boot application with Podman Desktop

October 19, 2023

Cedric Clyburn Related topics: ContainersJavaKubernetesSpring Boot Related products: Podman DesktopRed Hat Enterprise Linux

Share:

Spring and Spring Boot are developer favorites for building Java applications that run in the cloud. Spring is known for being production-ready, complimenting containerization very well. According to the State of Spring 2022 report, Kubernetes has become the dominant platform for running Spring apps. So, how can we take a Spring application, containerize it, and run it locally? Let’s explore this by using Podman Desktop, an open-source tool to seamlessly work with containers and Kubernetes from your local environment.

Prerequisites

  • Spring Boot Application: For this article, we’ll use the popular Spring PetClinic sample application on GitHub (Figure 1). Feel free to also use your own project or start from the Spring Initializr.
A screenshot of the Spring Pet clinic Repository on Github
Figure 1: The Spring Petclinic repository on Github.
  • Podman Desktop: Let’s use Podman Desktop, the powerful GUI-based tool for deploying and managing containers using the Podman container engine. Once installed, you’ll be ready to start containerizing your Spring application (Figure 2).
A screenshot of the Podman Desktop dashboard.
Figure 2: The Podman Desktop dashboard.

Containerizing the Spring Boot application

Let’s get started by cloning the application’s source code if using the PetClinic repository.

git clone https://github.com/spring-projects/spring-petclinic.git
cd spring-petclinic

While we can use Maven to build a jar file and run it, let’s jump straight into creating a Containerfile in the project’s root directory, which will serve as the blueprint for the container image we’ll create later (analogous to Docker’s Dockerfile). You can create the file with the command touch Containerfile or simply create it from your IDE. Let’s see what the Containerfile will look like for this sample Spring Boot application:

# Start with a base image that has Java 17 installed.
FROM eclipse-temurin:17-jdk-jammy

# Set a default directory inside the container to work from.
WORKDIR /app

# Copy the special Maven files that help us download dependencies.
COPY .mvn/.mvn

# Copy only essential Maven files required to download dependencies.
COPY mvnw pom.xml./

# Download all the required project dependencies.
RUN ./mvnw dependency:resolve

# Copy our actual project files (code, resources, etc.) into the container.
COPY src./src

# When the container starts, run the Spring Boot app using Maven.
CMD ["./mvnw", "spring-boot:run"]

Let’s take a deeper look at the components that make up this Containerfile:

  • FROM eclipse-temurin:17-jdk-jammy:
    • Purpose: This line sets the foundation for our container.
    • Deep Dive: It tells Podman to use a pre-existing image that already has Java 17 installed. Think of it as choosing a base flavor for a cake before adding more ingredients. We use the eclipse-temurin image because it’s a trusted source for Java installations.
  • WORKDIR /app:
    • Purpose: Designates a working space in our container.
    • Deep Dive: Containers have their own file system. Here, we’re telling Podman to set up a folder named ‘app’ and make it the default location for any subsequent operations.
  • COPY commands:
    • Purpose: They transfer files from our local system into the container.
    • Deep Dive: The first COPY grabs Maven’s configuration, a tool Java developers use to manage app dependencies. The second copies over the main files of our app: the Maven wrapper (mvnw) and the project’s details (pom.xml).
  • RUN ./mvnw dependency:resolve:
    • Purpose: Downloads necessary libraries and tools for the app.
    • Deep Dive: This command activates Maven to fetch everything our app needs to run. By doing this in the Containerfile, we ensure the container has everything packaged neatly.
  • COPY src./src:
    • Purpose: Add our actual application code.
    • Deep Dive: Our app’s logic, features, and resources reside in the src directory. We’re moving it into the container so that when the container runs, it has our complete app.
  • CMD [“./mvnw”, “spring-boot:run”]:
    • Purpose: Start our application!
    • Deep Dive: This command is the final step. This line tells Podman to run our Spring Boot application using Maven when our container launches.

This Containerfile is ready to be used with Podman Desktop to create a container image of our Spring Boot application (Figure 3). Before building the image for this application, let’s double check the directory structure and Containerfile in our IDE of choice.

A screenshot of the Containerfile in VSCode.
Figure 3: The Containerfile in VSCode.

Building the container image with Podman Desktop

We can now build our container image with Podman Desktop by first heading to the Images section of Podman Desktop and selecting the Build an Image button in the top-right corner (Figure 4).

A screenshot of the Podman Desktop with the build image button highlighted.
Figure 4: The Podman Desktop Build Image is highlighted.

This will open a menu where you can select the path to our previously created Containerfile, which should be in the root directory of the spring-petclinic folder. With the Containerfile selected, we can also give our container image a name, for example, petclinic. Now, click on Build, and you’ll see each of the layers of the image being created. You can find this in your local image registry (the Image section in Figure 5).

A screenshot of the Podman Desktop build image menu.
Figure 5: The Podman Desktop Build Image menu.

Running the containerized application

Fantastic! Let’s return to the Images section to see the containerized Spring Boot application, now built and tagged as an image, as well as the eclipse-temurin base image that was downloaded to build our petclinic image. We can easily run this image as a container on our system using the Run icon to the right of our container image (Figure 6).

A screenshot of the Podman Desktop run container.
Figure 6: The Podman Desktop showing where to run the container.

Under Port Mapping, make sure to assign port 8080 of the container to port 8080 of the host. Feel free to leave all other settings as default. Click Start Container to launch the containerized instance of your Spring Boot application (Figure 7).

A screenshot showing the start container button in the Podman Desktop menu.
Figure 7: Click the start container button in the Podman Desktop menu.

Now, with the container up and running, let’s open the container’s URL in the browser using the handy open browser button within the Podman Desktop user interface (Figure 8).

A screenshot of the Podman Desktop highlighting the open browser button.
Figure 8: The Podman Desktop highlighting the open browser button.

Perfect, looks like our Spring Boot application is running, thanks to the startup command in our Containerfile, as well as the port mapping we configured in Podman Desktop (Figure 9).

A screenshot showing the Spring Boot application is running in Chrome.
Figure 9: The Spring Boot application is running in Chrome.

Now we can see this PetClinic application running in our browser, but that’s not all. For more features that may involve bringing out the terminal, we can now use Podman Desktop instead (Figure 10). This may include, SSH’ing into a container for debugging and modifying settings, maybe viewing the logs of a container, or inspecting environment variables. This can all be done under the Container Details section that opens automatically after starting the container.

A screenshot of the Podman Desktop terminal.
Figure 10: The Podman Desktop terminal.

Wrapping up

We have gone from local Spring Boot code to containerizing the application and running it with Podman Desktop! Now, as a container, we can share this application across environments using registries like Quay.io and Docker Hub and deploy it using Kubernetes and OpenShift to a variety of different cloud providers.Last updated: January 15, 2025

Related Posts

Recent Posts

What’s up next?

Read Podman in Action for easy-to-follow examples to help you learn Podman quickly, including steps to deploy a complete containerized web service. LinkedInYouTubeTwitterFacebook

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

© 2025 Red Hat

https://www.google.com/recaptcha/api2/bframe?hl=en&v=Lu6n5xwy2ghvnPNo3IxkhcCb&k=6LfI4RApAAAAAF0FZDNh0WxeTb5vW26PPphSO9CR&bft=0dAFcWeA4cWuzQUGkfsrWOK2bL2tgkxlHUWBM7aegdByjKYGUp9Bscf1mdedF5sLmoYL8ru6xp1vPOFU6FF0l_bIY8xaZM4xN2sg

Install Podman Desktop on Debian (without flatpak) March 27, 2024

FONT: https://aliefee.page/blog/post/install-podman-desktop-on-debian-without-flatpak#install-podman-desktop-on-debian-without-flatpak-

Install Podman Desktop on Debian (without flatpak)

Since there is no official Debian package for Podman Desktop, we need to download the official binary archive and install it manually, in case you don’t want to use Flatpak.

This tutorial assumes:

  • You have a working Debian installation (or a Debian based distro like Ubuntu, Linux Mint, Kali, MX Linux etc.)
  • You are comfortable with using terminal and have sudo access
  • You have the latest stable podman installed on your machine. If not just run: sudo apt install podman

1.Download Podman Desktop

First, head over to Podman Desktop Download page and download the latest version archive.

Podman Desktop Download Page

2.Move the downloaded file to /opt

We will install Podman Desktop inside /opt directory. Open your terminal and move the downloaded file to /opt.
Now open terminal and run the command below.
Change <download-directory> and <version> with the path to directory where you downloaded the file and the version you downloaded.

sudo mv <download-directory>/podman-desktop-<version>.tar.gz /opt

3.Extract the archive

cd /opt
sudo tar -xvf podman-desktop-<version>.tar.gz
sudo rm podman-desktop-<version>.tar.gz

sudo mv podman-desktop-<version> podman-desktop

On the question of why we put binaries into /opt:
It is recommended to install software from official repositories whenever possible to avoid clashes of different packaging of the same software. But in our case, since there is no official Debian package for Podman Desktop as of the date i composed this tutorial (March 2024), we installed it into /opt as a convention.
You can read further about the Filesystem Hierarchy Standard https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s13.html

I recommend you to check if there is an official package available in apt repositories before going ahead:

apt search podman-desktop

If you find an official package, you can install it using apt. And you can easily retract the process at this step easily:

sudo rm -rf /opt/podman-desktop-*

Ensuring podman-desktop can be executed

sudo chmod +x /opt/podman-desktop/podman-desktop

At this step, we will put a symbolic link in /usr/local/bin directory.
So that it can be executed in your terminal

sudo ln -s /opt/podman-desktop/podman-desktop /usr/local/bin/podman-desktop

You can check if you can run podman-desktop from your terminal:

which podman-desktop
# /usr/local/bin/podman-desktop
# if you see this output, you are able to run podman-desktop from your terminal

5.Put a Desktop Entry

You can now run podman-desktop from your terminal.
But you will want to run it from your desktop environement’s menu too right?
To achieve that we need to create a .desktop file in /usr/local/share/applications

/usr/local/share/applications/podman-desktop.desktop

[Desktop Entry]
Name=Podman Desktop
Exec=podman-desktop
Terminal=false
Type=Application
Icon=podman-desktop
StartupWMClass=Podman Desktop
Categories=Development;

let’s do it with a few commands:

cd /tmp
echo -e "[Desktop Entry]\nName=Podman Desktop\nExec=podman-desktop\nTerminal=false\nType=Application\nIcon=podman-desktop\nStartupWMClass=Podman Desktop\nCategories=Development;" > podman-desktop.desktop
sudo desktop-file-install --dir=/usr/local/share/applications ./podman-desktop.desktop
rm podman-desktop.desktop

6.[Optional] Install icon file

You can copy and run all the commands at once

cd /tmp
wget https://aliefee.page/podman-desktop-icons.tar # download
tar -xvf podman-desktop-icons.tar # extract
mv podman-desktop-icons icons # rename
sudo cp -r ./icons /usr/local/share # copy
rm -rf icons podman-desktop-icons.tar # clean up

Congrats! You have now Podman Desktop set and up perfectly!

Containers in 2025: Docker vs. Podman for Modern Developers

FONT: https://www.linuxjournal.com/content/containers-2025-docker-vs-podman-modern-developers

Containers in 2025: Docker vs. Podman for Modern Developers

by George Whittaker

on August 26, 2025

Containers in 2025: Docker vs. Podman for Modern Developers

Introduction

Container technology has matured rapidly, but in 2025, two tools still dominate conversations in developer communities: Docker and Podman. Both tools are built on OCI (Open Container Initiative) standards, meaning they can build, run, and manage the same types of images. However, the way they handle processes, security, and orchestration differs dramatically. This article breaks down everything developers need to know, from architectural design to CLI compatibility, performance, and security, with a focus on the latest changes in both ecosystems.

Architecture: Daemon vs. Daemonless

Docker’s Daemon-Based Model

Docker uses a persistent background service, dockerd, to manage container lifecycles. The CLI communicates with this daemon, which supervises container creation, networking, and resource allocation. While this centralized approach is convenient, it introduces a single point of failure: if the daemon crashes, every running container goes down with it.Podman’s Daemonless Approach

Podman flips the script. Instead of a single daemon, every container runs as a child process of the CLI command that started it. This design eliminates the need for a root-level service, which is appealing for environments concerned about attack surfaces. Containers continue to run independently even if the CLI session ends, and they can be supervised with systemd for long-term stability.

Developer Workflow and CLI

Familiar Command Structure

Podman was designed as a near drop-in replacement for Docker. Commands like podman run, podman ps, and podman build mirror their Docker equivalents, reducing the learning curve. Developers can often alias docker to podman and keep using their existing scripts.

Run an NGINX container

Docker

docker run -d --name web -p 8080:80 nginx:latest

Podman

podman run -d --name web -p 8080:80 nginx:latest

GUI Options

For desktop users, Docker Desktop remains polished and feature-rich. However, Podman Desktop has matured significantly. It now supports Windows and macOS with better integration, faster file sharing, and no licensing restrictions, making it appealing for enterprise environments.

Image Building and Management

Docker’s BuildKit

Docker’s modern builds leverage BuildKit, enabling parallelized builds, advanced caching, and multi-architecture support. This makes building complex applications efficient and portable across ARM and x86 environments.Podman with Buildah

Podman integrates with Buildah, enabling rootless image building, a huge win for CI/CD pipelines. Recent versions also added distributed builds (podman farm build), making it easier to scale builds across multiple systems, a feature Docker introduced earlier with BuildKit.

Build an image with Podman

podman build -t myapp:latest .

Rootless Containers

Rootless operation is where Podman truly shines. From the ground up, Podman runs containers as a regular user, mapping the root user inside the container to a non-privileged user on the host. Docker added rootless support later, but it’s still not the default configuration. For developers working in multi-user systems or shared CI runners, Podman’s approach is safer and easier to configure.

Security Considerations

  • Podman minimizes risks by avoiding a long-running privileged daemon and using tighter default permissions.
  • Docker, while improved with rootless mode and better defaults in Docker Engine 28, still defaults to rootful mode in many deployments.
  • Both support SELinux, AppArmor, and Seccomp for additional isolation, but Podman’s integration is deeper in SELinux-enabled environments.

Kubernetes and Orchestration

Docker and Compose

Docker remains a leader for local development with Docker Compose, offering a quick way to spin up multi-container stacks. For clustering, Docker Swarm still exists but has mostly stagnated.Podman and Kubernetes Alignment

Podman embraces a Kubernetes-first design. It allows creating pods locally, exporting manifests with podman generate kube, and even running those manifests directly with podman play kube. This makes Podman an excellent choice for teams moving workloads to Kubernetes.

Generate Kubernetes YAML from a running Podman pod

podman generate kube mypod > mypod.yaml

Performance and Resource Usage

  • Startup Speed: Docker is marginally faster when starting individual containers because the daemon is always running.
  • Idle Overhead: Podman wins here, no daemon means zero baseline memory usage when idle.
  • Scalability: Podman handles many concurrent containers more gracefully since there’s no central bottleneck.
  • Rootless I/O: Thanks to kernel-level improvements, Podman’s rootless file I/O performance now matches Docker’s native overlay driver performance.

Ecosystem and Compatibility

  • Docker’s API compatibility remains a huge advantage, with wide support in third-party tools and CI systems.
  • Podman has bridged much of this gap with a Docker-compatible API service, enabling tools like Jenkins or Terraform to interact with it almost transparently.
  • Docker Hub remains the dominant public image registry, but Podman works with all OCI-compliant registries seamlessly.

Practical Use Cases

ScenarioPreferred Tool
Multi-user Linux serversPodman
Legacy pipelines using Docker APIDocker
CI/CD with rootless buildsPodman
Desktop dev with Kubernetes clusterDocker Desktop or Podman Desktop
Windows container workloadsDocker

Future Outlook

The rivalry between Docker and Podman is less about one replacing the other and more about choosing the right tool for the job. With both runtimes embracing OCI standards and converging on feature parity, developers have the flexibility to mix and match based on project needs. Expect to see:

  • More integrations supporting both runtimes.
  • Continued emphasis on rootless security.
  • Deeper Kubernetes alignment, especially from Podman.

Final Thoughts

Docker and Podman in 2025 represent two mature, powerful tools. Docker excels in compatibility and ease of onboarding, while Podman provides advanced security and a Kubernetes-centric approach. For developers, the good news is clear: whether you choose Docker, Podman, or even both in different environments, your workflows remain fast, secure, and future-proof.

George Whittaker is the editor of Linux Journal, and also a regular contributor. George has been writing about technology for two decades, and has been a Linux user for over 15 years. In his free time he enjoys programming, reading, and gaming.