Podman is a container engine that’s compatible with the OCI Containers specification. It is part of RedHat Linux, but can also be installed on other distributions. As it’s OCI-compliant, Podman can be used as a drop-in replacement for the better-known Docker runtime. Most Docker commands can be directly translated to Podman commands. Podman implements almost all the Docker CLI commands (apart from the ones related to Docker Swarm).
Podman complements Buildah and Skopeo by offering an experience similar to the Docker command line: allowing users to run standalone (non-orchestrated) containers. And Podman doesn’t require a daemon to run containers and pods, so we can easily say goodbye to big fat daemons. There are no daemons in the background doing stuff, and this means that Podman can be integrated into system services through systemd
.
In this guide we will learn how to install Podman in OpenSUSE Leap.
Related posts
- How to install and use Podman in Debian 11
- How to install and use Podman in Rocky Linux/Alma Linux/Centos 8
- How to install and use Podman in Fedora 34/35
- How to install and configure docker In Rocky Linux/Centos 8
- Getting Started With Docker Compose With Examples
- Docker as a build agent – Run Jenkins builds on Docker
Prerequisites
To follow along, ensure that you have the following:
- An updated OpenSUSE LEAP Server/Workstation
- Root access or User with sudo access
- Access to the internet
Table of content
- Ensuring that the server is up to date
- Installing podman
- Command line examples
- Runa postgres persistent container
- Managing containers as system services through systemd and Podman
1. Ensuring that the server is up to date
Use this command to ensure that our server packages are updated
sudo zypper ref
sudo zypper update -y
Let us ensure common packages are installed
sudo zypper install -y vim
2. Installing Podman
Podman is available in the default repositories for OpenSUSE. Install it using this command:
sudo zypper install -y podman
This command will install Podman and also its dependencies.
That’s all. Now we can now play with Podman.
3. Command line examples
Let us explore running OpenSUSE Leap Container using podman.
On docker we would use this command to run an OpenSUSE Leap container:
docker run -it opensuse/leap:15.3 sh
This will fail since there is no docker
command on my OpenSUSE machine. We can replace docker with podman:
podman run -it <meta charset="utf-8">opensuse/leap:15.3 sh
Let us run some commands to confirm that it is working as expected:
~> podman run -it opensuse/leap:15.3 sh
Trying to pull registry.opensuse.org/opensuse/leap:15.3...
Getting image source signatures
Copying blob 7bc46307c67f done
Copying config 09d5e2cf44 done
Writing manifest to image destination
Storing signatures
sh-4.4# whoami
root
sh-4.4# cat /etc/os-release
NAME="openSUSE Leap"
VERSION="15.3"
ID="opensuse-leap"
ID_LIKE="suse opensuse"
VERSION_ID="15.3"
PRETTY_NAME="openSUSE Leap 15.3"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:15.3"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
sh-4.4#
To check the container status use podman ps
command
~> podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eaa09408b382 registry.opensuse.org/opensuse/leap:15.3 sh 53 seconds ago Exited (0) 13 seconds ago priceless_curran
To delete the container, use podman rm
:
~> podman rm eaa09408b382
eaa09408b382ceb33a4696fed282e76df5130abf556b085ddc199eb30af54c8c
To list the images:
~> podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.opensuse.org/opensuse/leap 15.3 09d5e2cf44af 2 weeks ago 111 MB
We can delete the image using the image podman image rm
command:
~> podman image rm opensuse/leap:15.3
Untagged: registry.opensuse.org/opensuse/leap:15.3
Deleted: 09d5e2cf44af39c62b803e65991d700d8300dc34d82ff03c9cf359b9e092177a
From the above, we can confirm that the podman commandn uses the same syntax as docker
4. Run a Postgres persistent container
Next, let us explore how we can run a persistent container. In this example, we are going to run a Postgres 14 container and mount the postgres data to a local volume so it can persist restarts. Since containers are ephimeral, data will be lost if we do not save in a local volume.
Pull docker.io/library/postgres:14.0-alpine
image
~> podman image rm opensuse/leap:15.3
Untagged: registry.opensuse.org/opensuse/leap:15.3
Deleted: 09d5e2cf44af39c62b803e65991d700d8300dc34d82ff03c9cf359b9e092177a
ec2-user@ip-10-2-40-188:~> podman pull docker.io/library/postgres:14.0-alpine
Trying to pull docker.io/library/postgres:14.0-alpine...
Getting image source signatures
Copying blob 82e9eb77798b done
Copying blob 5034a66b99e6 done
Copying blob 3da258773353 done
Copying blob c6b2245b2f36 done
Copying blob a0d0a0d46f8b done
Copying blob ccd761727716 done
Copying blob 028554d3b6cc done
Copying blob 2c7ee7bc69e8 done
Copying config 87440f4e7f done
Writing manifest to image destination
Storing signatures
87440f4e7f9e60607dc11a4f0590a1c69b3a1c075211df478e22b0c27fb263e6
Confirm images
~> podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/postgres 14.0-alpine 87440f4e7f9e 2 weeks ago 198 MB
Inspect the image with
$ podman inspect <meta charset="utf-8">87440f4e7f9e
Let’s set up a folder that will handle Postgres data once we start our container:
$ mkdir -p ~/apps/postgres/data
Run it
podman run -d \
-p 5432:5432 \
-v ~/apps/postgres/data:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=Sup3rSecre7 \
-e POSTGRES_USER=citizix_user \
-e POSTGRES_DB=citizix_db \
docker.io/library/postgres:14.0-alpine
This is my output
~> podman run -d \
> -p 5432:5432 \
> -v ~/apps/postgres/data:/var/lib/postgresql/data \
> -e POSTGRES_PASSWORD=Sup3rSecre7 \
> -e POSTGRES_USER=citizix_user \
> -e POSTGRES_DB=citizix_db \
> docker.io/library/postgres:14.0-alpine
1607081ed241073e20e6186543c1882e977f2a91c9c061ccdd36a3e357051a44
Check processes:
~> podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1607081ed241 docker.io/library/postgres:14.0-alpine postgres 11 seconds ago Up 10 seconds ago 0.0.0.0:5432->5432/tcp happy_jang
Confirm the container logs with this. You can see that it is initializing the db
~> podman logs 1607081ed241 | head The files belonging to this database system will be owned by user "postgres". This user must also own the server process. The database cluster will be initialized with locale "en_US.utf8". The default database encoding has accordingly been set to "UTF8". The default text search configuration will be set to "english". Data page checksums are disabled. fixing permissions on existing directory /var/lib/postgresql/data ... ok
Let us connect to the database and do some operations
$ podman exec -it <meta charset="utf-8">1607081ed241 /bin/bash
bash-5.1# psql -U citizix_user -d citizix_db;
psql (14.0)
Type "help" for help.
citizix_db=# select version();
version
--------------------------------------------------------------------------------------------------------------
PostgreSQL 14.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424, 64-bit
(1 row)
citizix_db=#
Next let us explore killing and removing the container. We can use podman kill
to stop the container. This will stop the container, but it will still be there. Use podman ps -a
to list. To complately remove it then podman rm -f
.
~> podman kill 1607081ed241
1607081ed241073e20e6186543c1882e977f2a91c9c061ccdd36a3e357051a44
~> podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1607081ed241 docker.io/library/postgres:14.0-alpine postgres About a minute ago Exited (137) 15 seconds ago 0.0.0.0:5432->5432/tcp happy_jang
~> podman rm -f 1607081ed241
1607081ed241073e20e6186543c1882e977f2a91c9c061ccdd36a3e357051a44
5. Managing containers as system services through systemd and Podman
We can manage podman containers through systemd. Let us create a systemd
resource file for handling the postgres container we just created above.
Create a postgres podman file:
sudo vim /etc/systemd/system/postgres-podman.service
Add this content
[Unit]
Description=Custom Postgres Podman Container
After=network.target
[Service]
Type=simple
TimeoutStartSec=5m
ExecStartPre=-/usr/bin/podman rm -f postgrespodman
ExecStart=/usr/bin/podman run \
-p 5432:5432 \
-v /home/ec2-user/apps/postgres/data:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=Sup3rSecre7 \
-e POSTGRES_USER=citizix_user \
-e POSTGRES_DB=citizix_db \
docker.io/library/postgres:14.0-alpine
ExecReload=-/usr/bin/podman stop postgrespodman
ExecReload=-/usr/bin/podman rm postgrespodman
ExecStop=-/usr/bin/podman stop postgrespodman
Restart=always
RestartSec=30
[Install]
Then we can reload the systemd
catalog and start the service:
sudo systemctl daemon-reload
sudo systemctl start postgres-podman
Confirm the service status
~> sudo systemctl status postgres-podman
● postgres-podman.service - Custom Postgres Podman Container
Loaded: loaded (/etc/systemd/system/postgres-podman.service; static)
Active: active (running) since Mon 2021-11-15 05:40:34 UTC; 12s ago
Process: 23658 ExecStartPre=/usr/bin/podman rm -f postgrespodman (code=exited, status=1/FAILURE)
Main PID: 23687 (podman)
Tasks: 12 (limit: 4587)
CGroup: /system.slice/postgres-podman.service
├─23687 /usr/bin/podman run -p 5432:5432 -v /home/ec2-user/apps/postgres/data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=Sup3rSecre7 -e POSTG>
└─23828 /usr/bin/conmon --api-version 1 -c 8a18a63727ecd19d03710544e3e7ee9241e886d9fed45c1f25e29547ab61d600 -u 8a18a63727ecd19d03710544e3e7ee924>
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.477 UTC [1] LOG: starting PostgreSQL 14.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine>
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.478 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.478 UTC [1] LOG: listening on IPv6 address "::", port 5432
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.482 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.486 UTC [22] LOG: database system was interrupted; last known up at 2021-11-15 05:35:02 UTC
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.497 UTC [22] LOG: database system was not properly shut down; automatic recovery in progre>
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.499 UTC [22] LOG: redo starts at 0/16FAD98
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.499 UTC [22] LOG: invalid record length at 0/16FADD0: wanted 24, got 0
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.499 UTC [22] LOG: redo done at 0/16FAD98 system usage: CPU: user: 0.00 s, system: 0.00 s, >
Nov 15 05:40:35 ip-10-2-40-188 podman[23687]: 2021-11-15 05:40:35.509 UTC [1] LOG: database system is ready to accept connections
We just set up a custom system service based on a container managed through Podman!
Conclusion
We managed to explore how to install Podman in our OpenSUSE Leap server in this guide.