Podman Desktop for Java Development
Install Podman Desktop for managing containers and learn how to use it for Java development (Spring Boot, Quarkus, Testcontainers, Buildpacks).
Podman is a solution to manage containers, pods, and images in a container or Kubernetes environment. It complies with OCI standards and can be used as an alternative to Docker.
Podman Desktop is a convenient GUI on top of Podman to simplify container management across different operating systems and runtimes, including Kubernetes.
Both Podman and Podman Desktop are fully open-source and free to use. They are part of a broader set of container tools backed by an active community and supported by Red Hat.
This article will show how to install Podman and Podman Desktop, and how to configure them to make them ready for Java development.
Installing Podman Desktop
Let's start by installing Podman and Podman Desktop. On macOS and Linux, you can use the Homebrew package manager.
brew install podman
brew install podman-desktop
On Windows, you can use the Winget package manager.
winget install -e --id RedHat.Podman
winget install -e --id RedHat.Podman-Desktop
For additional install options, check the project documentation.
After the installation is complete, open Podman Desktop. If you have Docker Desktop running, ensure you stop it before moving on.
Next, go to Settings > Resources and click the "Create new..." button to initialize a new Podman Machine, which will start a lightweight virtual machine with Linux and the Podman Engine installed.
podman machine
subcommands to create and manage Podman Machines. Podman Desktop is not required, but it simplifies and automates the process.Leave the default name for the Podman Machine and configure CPU, memory, and disk space based on your needs.
Finally, click the "Run" button to start the Podman Machine you have just created.
Next time you start Podman Desktop, the Podman Machine you have configured will be automatically started. That's one of the advantages of using Podman Desktop.
Let's now verify that Podman is working correctly by running a container. We'll use one of the Chainguard Images ("hardened images with 0-known vulnerabilities, a minimal footprint, and SBOMs").
podman run --name demo-podman cgr.dev/chainguard/busybox echo Hello Podman!
The result should be the "Hello Podman!" message printed on the console. You can get more information about the container from Podman Desktop.
Awesome! Podman Desktop is now correctly installed. Next, I'll show you how you can keep using the Docker and Docker Compose CLIs on top of Podman.
Using Docker and Docker Compose with Podman
The most used commands in the Docker CLI are also available in the Podman CLI. For most use cases, you can define an alias to replace docker
commands with podman
commands (for example, alias docker=podman
).
However, you don't need to configure any alias with Podman Desktop as it provides compatibility with Docker out-of-the-box, which makes it possible to keep using the Docker and Docker Compose CLIs on top of Podman.
Let's try that out by running the same container image as before, but this time using the Docker CLI.
docker run --name demo-docker cgr.dev/chainguard/busybox echo Hello Podman!
Cannot connect to the Docker daemon at unix:///Users/<user>/.docker/run/docker.sock. Is the docker daemon running?
. In that case, make sure you switch to the default Docker context with docker context use default
and try again. For more information why that is needed, check out the GitHub issues on the Podman and Podman Desktop projects where this issue is being addressed.Even if using the Docker CLI, the container ran on Podman.
podman ps -a --format '{{ .Names }} {{ .Image }}'
The result should be similar to the following.
demo-podman cgr.dev/chainguard/busybox:latest
demo-docker cgr.dev/chainguard/busybox:latest
Similarly, you can keep using Docker Compose for running containers on Podman. Create a docker-compose.yml
file with the following content.
services:
postgres:
image: "cgr.dev/chainguard/postgres:15"
container_name: postgres
ports:
- 5432:5432
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=books
Then, use Docker Compose to run the PostgreSQL service on Podman.
docker compose up -d
Even if using Docker Compose, the container is running on Podman. You can check its logs with the following command.
podman logs postgres
Podman Desktop shows the status of the Docker and Docker Compose compatibility in Podman (bottom-left part of the console).
The out-of-the-box compatibility layer works well with both the Docker and Docker Compose CLIs. The next section will cover how to extend the compatibility layer to cover more use cases when root permissions are required.
Configuring Podman as Rootful
Docker requires root privileges to run containers. On the other hand, Podman runs without root privileges by default for enhanced security. That means that tools like Cloud Native Buildpacks, Testcontainers, and Spring Boot Docker Compose will not work if Podman runs in rootless mode.
A Podman Machine can be configured to run either in rootless (the default) or rootful mode. Stop and delete the machine created earlier from the Podman Desktop GUI or the CLI.
podman machine stop
podman machine rm
We'll now create a new Podman Machine in rootful mode. Open Podman Desktop, go to Settings > Resources and click the "Create new..." button to initialize a new Podman Machine. Like before, leave the default name for the Podman Machine and configure CPU, memory, and disk space based on your needs. Additionally, ensure the "Machine with root privileges" setting is set to "Enabled".
Finally, in the Settings > Resources page, click the "Run" button to start the Podman Machine you have just created.
Let's verify that it works. We'll use Spring Boot as an example. First, check out the following Git repository.
git clone https://github.com/ThomasVitale/spring-tutorials.git
cd spring-boot-docker-compose
Since version 3.1, Spring Boot can automatically start and stop containers from a Docker Compose file when running an application in development.
./gradlew bootRun
sdk install java 20-tem
.As you can see from the application logs, Spring Boot uses the docker-compose.yml
file included in the repository (spring-boot-docker-compose/docker-compose.yml
) to start a PostgreSQL container as part of the application lifecycle. Since we configured the Docker compatibility layer in Podman, the container is run on Podman.
Let's now try the Cloud Native Buildpacks integration in Spring Boot, which also requires a Docker daemon. Stop the previous process (Ctrl-C
) and then use the bootBuildImage
task to containerize the application.
./gradlew bootBuildImage
The result will be an OCI image called book-service
that you can run on any OCI-compliant runtime, including Podman, Docker, and Kubernetes.
Similarly, you can use the Cloud Native Buildpacks integration in Quarkus on top of Podman using the ./gradlew build -Dquarkus.container-image.build=true
command.
Configuring Testcontainers for Podman
Running Testcontainers on Podman requires the rootful mode, but that's not enough. You must also update the ~/.testcontainers.properties
file with the following line (or create the file if it doesn't exist yet).
ryuk.container.privileged=true
Let's give it a try with another Spring Boot example.
git clone https://github.com/ThomasVitale/spring-tutorials.git
cd spring-boot-testcontainers
The application relies on a PostgreSQL database and uses Testcontainers to run integration tests against an actual database instance as a container.
./gradlew test
Starting from Spring Boot 3.1, Testcontainers can also be used to launch a PostgreSQL container when running the application at development time. Let's verify that works, too.
./gradlew bootTestRun
As you can see from the application logs, Spring Boot uses the Testcontainers configuration (TestBookServiceApplication.java
) to start a container as part of the application lifecycle. Since we configured the Docker compatibility layer in Podman, the container is run on Podman.
Similarly, the Testcontainers integration in Quarkus can now work on Podman, including for running tests and dev services.
Working with Podman Compose
As described in a previous section, you can keep using the Docker Compose CLI on top of Podman. If you prefer not to install additional CLIs from Docker, check out the Podman Compose project.
Podman Compose is an implementation of the Docker Compose specification based on Podman. On macOS and Linux, you can install Podman Compose from the Homebrew package manager. Check the project documentation for additional installation options.
brew install podman-compose
Create a podman-compose.yml
file with the following content.
services:
postgres:
image: "cgr.dev/chainguard/postgres:15"
container_name: postgres
ports:
- 5432:5432
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=books
Then, use Podman Compose to run the PostgreSQL service on Podman.
podman-compose up -d
You can verify the container is up and running via the Podman CLI.
podman ps
When you're done testing, you can bring the container down as follows.
podman-compose down
Conclusion
Podman Desktop is an excellent solution for managing containers across different runtimes (such as Podman, Docker, and Lima). The only feature I miss and that's currently being planned is support for a light mode in the GUI, which would make it more accessible to a wider audience (follow the issue on GitHub for status updates).
If you're migrating from Docker, I recommend checking the blog post 5 things to know about Podman Desktop for a Docker user on the Podman Desktop website.
In this article, I covered the features related to container management and configurations relevant for Java development, but Podman Desktop can do much more than that.
It provides convenient features to work with Kubernetes. For example, you can start a new local cluster with kind, including the Contour ingress controller and the possibility to expose all your Kubernetes services to your localhost automatically. And it can be extended via plugins. For example, you can run an OpenShift cluster with one single click.
Are you using Podman or Podman Desktop? What's your experience? I'd like to hear from you in the comments section!
Cover picture from Pexels.