Is Podman a Drop-In Replacement for Docker?
In this blog, you will start with a production-ready Dockerfile and execute the Podman commands just like you would do when using Docker.
Join the DZone community and get the full member experience.
Join For FreeIn many places, you can read that Podman is a drop-in replacement for Docker. But is it as easy as it sounds? In this blog, you will start with a production-ready Dockerfile and execute the Podman commands just like you would do when using Docker. Let’s investigate whether this works without any problems!
Introduction
Podman is a container engine, just as Docker is. Podman, however, is a daemonless container engine, and it runs containers by default as rootless containers. This is more secure than running containers as root. The Docker daemon can also run as a non-root user nowadays.
Podman advertises on its website that Podman is a drop-in replacement for Docker. Just add alias docker=podman
, and you will be fine. Let’s investigate whether it is that simple. In the remainder of this blog, you will try to build a production-ready Dockerfile for running a Spring Boot application. You will run it as a single container, and you will try to run two containers and have some inter-container communication. In the end, you will verify how volumes can be mounted.
One of the prerequisites for this blog is using a Linux operating system. Podman is not available for Windows.
The sources used in this blog can be found at GitHub.
The Dockerfile you will be using runs a Spring Boot application. It is a basic Spring Boot application containing one controller which returns a hello message.
Build the jar:
$ mvn clean verify
Run the jar:
$ java -jar target/mypodmanplanet-0.0.1-SNAPSHOT.jar
Check the endpoint:
$ curl http://localhost:8080/hello
Hello Podman!
The Dockerfile is based on a previous blog about Docker best practices. The file 1-Dockerfile-starter
can be found in the Dockerfiles
directory.
FROM eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f AS builder
WORKDIR application
ARG JAR_FILE
COPY target/${JAR_FILE} app.jar
RUN java -Djarmode=layertools -jar app.jar extract
FROM eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f
WORKDIR /opt/app
RUN addgroup --system javauser && adduser -S -s /usr/sbin/nologin -G javauser javauser
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
RUN chown -R javauser:javauser .
USER javauser
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
Prerequisites
Prerequisites for this blog are:
- Basic Linux knowledge, Ubuntu 22.04 is used during this post;
- Basic Java and Spring Boot knowledge;
- Basic Docker knowledge;
Installation
Installing Podman is quite easy. Just run the following command.
$ sudo apt-get install podman
Verify the correct installation.
$ podman --version
podman version 3.4.4
\You can also install podman-docker
, which will create an alias when you use docker
in your commands. It is advised to wait for the conclusion of this post before you install this one.
Build Dockerfile
The first thing to do is to build the container image. Execute from the root of the repository the following command.
$ podman build . --tag mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT -f Dockerfiles/1-Dockerfile-starter --build-arg JAR_FILE=mypodmanplanet-0.0.1-SNAPSHOT.jar
[1/2] STEP 1/5: FROM eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f AS builder
[2/2] STEP 1/10: FROM eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f
Error: error creating build container: short-name "eclipse-temurin@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"
This returns an error while retrieving the base image. The error message refers to /etc/containers/registries.conf
. The following is stated in this file.
# For more information on this configuration file, see containers-registries.conf(5).
#
# NOTE: RISK OF USING UNQUALIFIED IMAGE NAMES
# We recommend always using fully qualified image names including the registry
# server (full dns name), namespace, image name, and tag
# (e.g., registry.redhat.io/ubi8/ubi:latest). Pulling by digest (i.e.,
# quay.io/repository/name@digest) further eliminates the ambiguity of tags.
# When using short names, there is always an inherent risk that the image being
# pulled could be spoofed. For example, a user wants to pull an image named
# `foobar` from a registry and expects it to come from myregistry.com. If
# myregistry.com is not first in the search list, an attacker could place a
# different `foobar` image at a registry earlier in the search list. The user
# would accidentally pull and run the attacker's image and code rather than the
# intended content. We recommend only adding registries which are completely
# trusted (i.e., registries which don't allow unknown or anonymous users to
# create accounts with arbitrary names). This will prevent an image from being
# spoofed, squatted or otherwise made insecure. If it is necessary to use one
# of these registries, it should be added at the end of the list.
To conclude, it is suggested to use a fully qualified image name. This means that you need to change the lines containing:
eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f
Into:
docker.io/eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f
You just add docker.io/
to the image name. A minor change, but already one difference compared to Docker.
The image name is fixed in file 2-Dockerfile-fix-shortname
, so let’s try building the image again.
$ podman build . --tag mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT -f Dockerfiles/2-Dockerfile-fix-shortname --build-arg JAR_FILE=mypodmanplanet-0.0.1-SNAPSHOT.jar
[1/2] STEP 1/5: FROM docker.io/eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f AS builder
Trying to pull docker.io/library/eclipse-temurin@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f...
Getting image source signatures
Copying blob 72ac8a0a29d6 done
Copying blob f56be85fc22e done
Copying blob f8ed194273be done
Copying blob e5daea9ee890 done
[2/2] STEP 1/10: FROM docker.io/eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f
Error: error creating build container: writing blob: adding layer with blob "sha256:f56be85fc22e46face30e2c3de3f7fe7c15f8fd7c4e5add29d7f64b87abdaa09": Error processing tar file(exit status 1): potentially insufficient UIDs or GIDs available in user namespace (requested 0:42 for /etc/shadow): Check /etc/subuid and /etc/subgid: lchown /etc/shadow: invalid argument
Now there is an error about potentially insufficient UIDs or GIDs available in the user namespace. More information about this error can be found here. It is very well explained in that post, and it is too much to repeat all of this in this post. The summary is that the image which is trying to be pulled, has files owned by UIDs over 65.536. Due to that issue, the image would not fit into rootless Podman’s default UID mapping, which limits the number of UIDs and GIDs available.
So, how to solve this?
First, check the contents of /etc/subuid
and /etc/subgid
. In my case, the following is the output. For you, it will probably be different.
$ cat /etc/subuid
admin:100000:65536
$ cat /etc/subgid
admin:100000:65536
The admin
user listed in the output has 100.000 as the first UID or GID available, and it has a size of 65.536. The format is user:start:size
. This means that the admin
user has access to UIDs or GIDs 100.000 up to and including 165.535.
My current user is not listed here, and that means that my user can only allocate 1 UID en 1 GID for the container. That 1 UID/GID is already taken for the root user in the container. If a container image needs an extra user, there will be a problem, as you can see above.
This can be solved by adding UIDs en GIDs for your user. Let’s add values 200.000 up to and including 265.535 to your user.
$ sudo usermod --add-subuids 200000-265535 --add-subgids 200000-265535 <replace with your user>
Verify the contents of both files again. The user is added to both files.
$ cat /etc/subgid
admin:100000:65536
<your user>:200000:65536
$ cat /etc/subuid
admin:100000:65536
<your user>:200000:65536
Secondly, you need to run the following command.
$ podman system migrate
Try to build the image again, and now it works.
$ podman build . --tag mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT -f Dockerfiles/2-Dockerfile-fix-shortname --build-arg JAR_FILE=mypodmanplanet-0.0.1-SNAPSHOT.jar
[1/2] STEP 1/5: FROM docker.io/eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f AS builder
Trying to pull docker.io/library/eclipse-temurin@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f...
Getting image source signatures
Copying blob f56be85fc22e done
Copying blob f8ed194273be done
Copying blob 72ac8a0a29d6 done
Copying blob e5daea9ee890 done
Copying config c74d412c3d done
Writing manifest to image destination
Storing signatures
[1/2] STEP 2/5: WORKDIR application
--> d4f0e970dc1
[1/2] STEP 3/5: ARG JAR_FILE
--> ca97dcd6f2a
[1/2] STEP 4/5: COPY target/${JAR_FILE} app.jar
--> 58d88cfa511
[1/2] STEP 5/5: RUN java -Djarmode=layertools -jar app.jar extract
--> 348cae813a4
[2/2] STEP 1/10: FROM docker.io/eclipse-temurin:17.0.6_10-jre-alpine@sha256:c26a727c4883eb73d32351be8bacb3e70f390c2c94f078dc493495ed93c60c2f
[2/2] STEP 2/10: WORKDIR /opt/app
--> 4118cdf90b5
[2/2] STEP 3/10: RUN addgroup --system javauser && adduser -S -s /usr/sbin/nologin -G javauser javauser
--> cd11f346381
[2/2] STEP 4/10: COPY --from=builder application/dependencies/ ./
--> 829bffcb6c7
[2/2] STEP 5/10: COPY --from=builder application/spring-boot-loader/ ./
--> 2a93f97d424
[2/2] STEP 6/10: COPY --from=builder application/snapshot-dependencies/ ./
--> 3e292cb0456
[2/2] STEP 7/10: COPY --from=builder application/application/ ./
--> 5dd231c5b51
[2/2] STEP 8/10: RUN chown -R javauser:javauser .
--> 4d736e8c3bb
[2/2] STEP 9/10: USER javauser
--> d7a96ca6f36
[2/2] STEP 10/10: ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
[2/2] COMMIT mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT
--> 567fd123071
Successfully tagged localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT
567fd1230713f151950de7151da82a19d34f80af0384916b13bf49ed72fd2fa1
Verify the list of images with Podman just like you would do with Docker:
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/mydeveloperplanet/mypodmanplanet 0.0.1-SNAPSHOT 567fd1230713 2 minutes ago 209 MB
Is Podman a drop-in replacement for Docker for building a Dockerfile?
No, it is not a drop-in replacement because you needed to use the fully qualified image name for the base image in the Dockerfile, and you needed to make changes to the user namespace in order to be able to pull the image. Besides these two changes, building the container image just worked.
Start Container
Now that you have built the image, it is time to start a container.
$ podman run --name mypodmanplanet -d localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT
The container has started successfully.
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27639dabb573 localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT 18 seconds ago Up 18 seconds ago mypodmanplanet
You can also inspect the container logs.
$ podman logs mypodmanplanet
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.5)
2023-04-22T14:38:05.896Z INFO 1 --- [ main] c.m.m.MyPodmanPlanetApplication : Starting MyPodmanPlanetApplication v0.0.1-SNAPSHOT using Java 17.0.6 with PID 1 (/opt/app/BOOT-INF/classes started by javauser in /opt/app)
2023-04-22T14:38:05.898Z INFO 1 --- [ main] c.m.m.MyPodmanPlanetApplication : No active profile set, falling back to 1 default profile: "default"
2023-04-22T14:38:06.803Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-04-22T14:38:06.815Z INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-04-22T14:38:06.816Z INFO 1 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.7]
2023-04-22T14:38:06.907Z INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-04-22T14:38:06.910Z INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 968 ms
2023-04-22T14:38:07.279Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-04-22T14:38:07.293Z INFO 1 --- [ main] c.m.m.MyPodmanPlanetApplication : Started MyPodmanPlanetApplication in 1.689 seconds (process running for 1.911)
Verify whether the endpoint can be accessed.
$ curl http://localhost:8080/hello
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Connection refused
That’s not the case. With Docker, you can inspect the container to see which IP address is allocated to the container.
$ podman inspect mypodmanplanet | grep IPAddress
"IPAddress": "",
It seems that the container does not have a specific IP address. The endpoint is also not accessible at localhost.
The solution is to add a port mapping when creating the container.
Stop the container and remove it.
$ podman stop mypodmanplanet
mypodmanplanet
$ podman rm mypodmanplanet
27639dabb5730d3244d205200a409dbc3a1f350196ba238e762438a4b318ef73
Start the container again, but this time with a port mapping of internal port 8080 to an external port 8080.
$ podman run -p 8080:8080 --name mypodmanplanet -d localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT
Verify again whether the endpoint can be accessed. This time it works.
$ curl http://localhost:8080/hello
Hello Podman!
Stop and remove the container before continuing this blog.
Is Podman a drop-in replacement for Docker for running a container image?
No, it is not a drop-in replacement. Although it was possible to use exactly the same commands as with Docker, you needed to explicitly add a port mapping. Without the port mapping, it was not possible to access the endpoint.
Volume Mounts
Volume mounts and access to directories and files outside the container and inside a container often lead to Permission Denied errors. In a previous blog, this behavior is extensively described for the Docker engine. It is interesting to see how this works when using Podman.
You will map an application.properties
file in the container next to the jar file. The Spring Boot application will pick up this application.properties
file. The file configures the server port to port 8082, and the file is located in the directory properties
in the root of the repository.
server.port=8082
Run the container with a port mapping from internal port 8082 to external port 8083 and mount the application.properties
file into the container directory /opt/app
where also the jar file is located. The volume mount has the property ro
in order to indicate that it is a read-only file.
$ podman run -p 8083:8082 --volume ./properties/application.properties:/opt/app/application.properties:ro --name mypodmanplanet localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT
Verify whether the endpoint can be accessed and whether it works.
$ curl http://localhost:8083/hello
Hello Podman!
Open a shell in the container and list the directory contents in order to view the ownership of the file.
$ podman exec -it mypodmanplanet sh
/opt/app $ ls -la
total 24
drwxr-xr-x 1 javauser javauser 4096 Apr 15 10:33 .
drwxr-xr-x 1 root root 4096 Apr 9 12:57 ..
drwxr-xr-x 1 javauser javauser 4096 Apr 9 12:57 BOOT-INF
drwxr-xr-x 1 javauser javauser 4096 Apr 9 12:57 META-INF
-rw-r--r-- 1 root root 16 Apr 15 10:24 application.properties
drwxr-xr-x 1 javauser javauser 4096 Apr 9 12:57 org
With Docker, the file would have been owned by your local system user, but with Podman, the file is owned by root. Let’s check the permissions of the file on the local system.
$ ls -la
total 12
drwxr-xr-x 2 <myuser> domain users 4096 apr 15 12:24 .
drwxr-xr-x 8 <myuser> domain users 4096 apr 15 12:24 ..
-rw-r--r-- 1 <myuser> domain users 16 apr 15 12:24 application.properties
As you can see, the file on the local system is owned by <myuser>
. This means that your host user, who is running the container, is seen as a user root
inside of the container.
Open a shell in the container and try to change the contents of the file application.properties
. You will notice that this is not allowed because you are a user javauser
.
$ podman exec -it mypodmanplanet sh
/opt/app $ vi application.properties
/opt/app $ whoami
javauser
Stop and remove the container.
Run the container, but this time with property U
instead of ro. The U
suffix tells Podman to use the correct host UID and GID based on the UID and GID within the container to change the owner and group of the source volume recursively.
$ podman run -p 8083:8082 --volume ./properties/application.properties:/opt/app/application.properties:U --name mypodmanplanet localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT
Open a shell in the container, and now the user javauser
is the owner of the file.
$ podman exec -it mypodmanplanet sh
/opt/app $ ls -la
total 24
drwxr-xr-x 1 javauser javauser 4096 Apr 15 10:41 .
drwxr-xr-x 1 root root 4096 Apr 9 12:57 ..
drwxr-xr-x 1 javauser javauser 4096 Apr 9 12:57 BOOT-INF
drwxr-xr-x 1 javauser javauser 4096 Apr 9 12:57 META-INF
-rw-r--r-- 1 javauser javauser 16 Apr 15 10:24 application.properties
drwxr-xr-x 1 javauser javauser 4096 Apr 9 12:57 org
On the local system, a different UID and GID than my local user have taken ownership.
$ ls -la properties/
total 12
drwxr-xr-x 2 <myuser> domain users 4096 apr 15 12:24 .
drwxr-xr-x 8 <myuser> domain users 4096 apr 15 12:24 ..
-rw-r--r-- 1 200099 200100 16 apr 15 12:24 application.properties
This time, changing the file on the local system is not allowed, but it is allowed inside the container for user javauser
.
Is Podman a drop-in replacement for Docker for mounting volumes inside a container?
No, it is not a drop-in replacement. The file permissions function is a bit different than with the Docker engine. You need to know the differences in order to be able to mount files and directories inside containers.
Pod
Podman knows the concept of a Pod, just like a Pod in Kubernetes. A Pod allows you to group containers. A Pod also has a shared network namespace, and this means that containers inside a Pod can connect to each other. More information about container networking can be found here. This means that Pods are the first choice for grouping containers. When using Docker, you will use Docker Compose for this. There exists something like Podman Compose, but this deserves a blog in itself.
Let’s see how this works. You will set up a Pod running two containers with the Spring Boot application.
First, you need to create a Pod. You also need to expose the ports you want to be accessible outside of the Pod. This can be done with the -p
argument. And you give the Pod a name, hello-pod
in this case.
$ podman pod create -p 8080-8081:8080-8081 --name hello-pod
When you list the Pod, you notice that it already contains one container. This is the infra container. This infra container holds the namespace in order that containers can connect to each other, and it enables starting and stopping containers in the Pod. The infra container is based on the k8s.gcr.io/pause
image.
$ podman pod ps
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
dab9029ad0c5 hello-pod Created 3 seconds ago aac3420b3672 1
$ podman ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aac3420b3672 k8s.gcr.io/pause:3.5 4 minutes ago Created 0.0.0.0:8080-8081->8080-8081/tcp dab9029ad0c5-infra
Create a container mypodmanplanet-1
and add it to the Pod. By means of the --env
argument, you change the port of the Spring Boot application to port 8081.
$ podman create --pod hello-pod --name mypodmanplanet-1 --env 'SERVER_PORT=8081' localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT env
Start the Pod.
$ podman pod start hello-pod
Verify whether the endpoint can be reached at port 8081 and verify that the endpoint at port 8080 cannot be reached.
$ curl http://localhost:8081/hello
Hello Podman!
$ curl http://localhost:8080/hello
curl: (56) Recv failure: Connection reset by peer
Add a second container mypodmanplanet-2
to the Pod, this time running at the default port 8080.
$ podman create --pod hello-pod --name mypodmanplanet-2 localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT
Verify the Pod status. It says that the status is Degraded
.
$ podman pod ps
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
dab9029ad0c5 hello-pod Degraded 9 minutes ago aac3420b3672 3
Take a look at the containers. Two containers are running, and a new container is just created. That is the reason the Pod has the status Degraded
.
$ podman ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aac3420b3672 k8s.gcr.io/pause:3.5 11 minutes ago Up 2 minutes ago 0.0.0.0:8080-8081->8080-8081/tcp dab9029ad0c5-infra
321a62fbb4fc localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT env 3 minutes ago Up 2 minutes ago 0.0.0.0:8080-8081->8080-8081/tcp mypodmanplanet-1
7b95fb521544 localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT About a minute ago Created 0.0.0.0:8080-8081->8080-8081/tcp mypodmanplanet-2
Start the second container and verify the Pod status. The status is now Running.
$ podman start mypodmanplanet-2
$ podman pod ps
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
dab9029ad0c5 hello-pod Running 12 minutes ago aac3420b3672 3
Both endpoints can now be reached.
$ curl http://localhost:8080/hello
Hello Podman!
$ curl http://localhost:8081/hello
Hello Podman!
Verify whether you can access the endpoint of container mypodmanplanet-1
from within mypodmanplanet-2
. This also works.
$ podman exec -it mypodmanplanet-2 sh
/opt/app $ wget http://localhost:8081/hello
Connecting to localhost:8081 (127.0.0.1:8081)
saving to 'hello'
hello 100% |***********************************************************************************************************************************| 13 0:00:00 ETA
'hello' saved
Cleanup
To conclude, you can do some cleanup.
Stop the running Pod.
$ podman pod stop hello-pod
The Pod has the status Exited
now.
$ podman pod ps
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
dab9029ad0c5 hello-pod Exited 55 minutes ago aac3420b3672 3
All containers in the Pod are also exited.
$ podman ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aac3420b3672 k8s.gcr.io/pause:3.5 56 minutes ago Exited (0) About a minute ago 0.0.0.0:8080-8081->8080-8081/tcp dab9029ad0c5-infra
321a62fbb4fc localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT env 48 minutes ago Exited (143) About a minute ago 0.0.0.0:8080-8081->8080-8081/tcp mypodmanplanet-1
7b95fb521544 localhost/mydeveloperplanet/mypodmanplanet:0.0.1-SNAPSHOT 46 minutes ago Exited (143) About a minute ago 0.0.0.0:8080-8081->8080-8081/tcp mypodmanplanet-2
Remove the Pod.
$ podman pod rm hello-pod
The Pod and the containers are removed.
$ podman pod ps
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
$ podman ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Conclusion
The bold statement that Podman is a drop-in replacement for Docker is not true. Podman differs from Docker on certain topics like building container images, starting containers, networking, volume mounts, inter-container communication, etc. However, Podman does support many Docker commands. The statement should be Podman is an alternative to Docker. This is certainly true. It is important for you to know and understand the differences before switching to Podman. After this, it is definitely a good alternative.
Published at DZone with permission of Gunter Rotsaert, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments