How to install and use Podman in Debian 11

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 Debian 11.

# Prerequisites

To follow along, ensure that you have the following:

  • An updated Debian 11 Server/Workstation
  • Root access or User with sudo access
  • Access to the internet

# Table of content

  1. Ensuring that the server is up to date
  2. Installing podman
  3. Command line examples

# 1. Ensuring that the server is up to date

Use this command to ensure that our server packages are updated

sudo apt update && sudo apt upgrade -y

Let us ensure common packages are installed

sudo apt install -y vim

# 2. Installing Podman

Podman is available in the default Debian 11 repos. Install the podman engine using this command:

sudo apt install -y podman

This command will install Podman and also its dependencies.

To verify the version of Podman installed, run:

$ podman --version
podman version 3.0.1

That’s all. Now we can now play with Podman.

# 3. Command line examples

Let us explore running Debian Container using podman.

On docker we would use this command to run a

Debian container:
docker run -it debian:11-slim sh

This will fail since there is no docker command on my

Debian Server. We can replace docker with podman:
podman run -it <meta charset="utf-8">debian:11-slim sh

Let us run some commands to confirm that it is working as expected:

$ podman run -it debian:11-slim sh

Resolved "debian" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull docker.io/library/debian:11-slim...
Getting image source signatures
Copying blob 7d63c13d9b9b done
Copying config dd984c2cf0 done
Writing manifest to image destination
Storing signatures

# whoami
root
#

To check the container status use podman ps command

$ podman ps -a

CONTAINER ID  IMAGE                             COMMAND  CREATED             STATUS                     PORTS   NAMES
9c2338a4d143  docker.io/library/debian:11-slim  sh       About a minute ago  Exited (0) 41 seconds ago          hungry_mendel

To delete the container, use podman rm:

$ podman rm 9c2338a4d143
9c2338a4d143df611d6169e202ea965dfd4db25ee9cabacab759e12899da1fc6

To list the images:

$ podman images
REPOSITORY                TAG      IMAGE ID      CREATED      SIZE
docker.io/library/debian  11-slim  dd984c2cf05c  4 weeks ago  83.9 MB

We can delete the image using the image podman image rm command:

$ podman image rm debian:11-slim
Untagged: docker.io/library/debian:11-slim
Deleted: dd984c2cf05c58c61026b0bd2298b30aa87bca6f234db507396371137c891a6c

From the above, we can confirm that the podman command uses the same syntax as docker

# 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 pull docker.io/library/postgres:14.0-alpine
Trying to pull docker.io/library/postgres:14.0-alpine...
Getting image source signatures
Copying blob 3da258773353 done
Copying blob 5034a66b99e6 done
Copying blob 82e9eb77798b done
Copying blob a0d0a0d46f8b done
Copying blob ccd761727716 done
Copying blob c6b2245b2f36 done
Copying blob 2c7ee7bc69e8 done
Copying blob 028554d3b6cc 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 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:Z \
    -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:Z \
    -e POSTGRES_PASSWORD=Sup3rSecre7 \
    -e POSTGRES_USER=citizix_user \
    -e POSTGRES_DB=citizix_db \
    docker.io/library/postgres:14.0-alpine
5334f11b1566d93924d807dca404f782636c7fce0f38f4239977a5ce13d101be

Check processes:

$ podman ps
CONTAINER ID  IMAGE                                   COMMAND   CREATED         STATUS             PORTS                   NAMES
5334f11b1566  docker.io/library/postgres:14.0-alpine  postgres  27 seconds ago  Up 28 seconds ago  0.0.0.0:5432->5432/tcp  sharp_wu

Confirm the container logs with this. You can see that it is initializing the db

$ podman logs 


5334f11b1566 | 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">5334f11b1566 /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&nbsp;to list. To complately remove it then podman rm -f.

$ podman kill <meta charset="utf-8">5334f11b1566
5334f11b1566d93924d807dca404f782636c7fce0f38f4239977a5ce13d101be

$ podman ps -a
CONTAINER ID  IMAGE                                   COMMAND   CREATED        STATUS                       PORTS                   NAMES
5334f11b1566  docker.io/library/postgres:14.0-alpine  postgres  2 minutes ago  Exited (137) 10 seconds ago  0.0.0.0:5432->5432/tcp  sharp_wu

$ podman rm -f <meta charset="utf-8">5334f11b1566
5334f11b1566d93924d807dca404f782636c7fce0f38f4239977a5ce13d101be

# 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/admin/apps/postgres/data:/var/lib/postgresql/data:Z \
    -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 Fri 2021-11-12 05:49:57 UTC; 6s ago
    Process: 21032 ExecStartPre=/usr/bin/podman rm -f postgrespodman (code=exited, status=1/FAILURE)
   Main PID: 21056 (podman)
      Tasks: 16 (limit: 4626)
     Memory: 232.1M
        CPU: 7.055s
     CGroup: /system.slice/postgres-podman.service
             ├─21056 /usr/bin/podman run -p 5432:5432 -v /home/admin/apps/postgres/data:/var/lib/postgresql/data:Z -e POSTGRES_PASSWORD=Sup3rSecre7 ->
             └─21102 storage-untar / /var/lib/containers/storage/overlay/772aeee45322a287d8cfed4d3a774519a5a1bfb20750bf46584a8f7a9713fcaf/diff

Nov 12 05:49:59 ip-10-2-40-39 podman[21056]: Copying blob sha256:ccd761727716597fddb7d24aa4d7d68b3b638897b9351ccc295aa86407bd85e6
Nov 12 05:49:59 ip-10-2-40-39 podman[21056]: Copying blob sha256:82e9eb77798bd506a06a9adab733c822c718be829c54d514b5789b07c0f1c164
Nov 12 05:49:59 ip-10-2-40-39 podman[21056]: Copying blob sha256:3da258773353ad3725cb0ef73e28bd60fdd9078df3790b06b98198a86ef0424f
Nov 12 05:49:59 ip-10-2-40-39 podman[21056]: Copying blob sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e
Nov 12 05:49:59 ip-10-2-40-39 podman[21056]: Copying blob sha256:5034a66b99e67db609bf6b4f82bea915e39a42e6f03d11889f7406b4de9e99da
Nov 12 05:49:59 ip-10-2-40-39 podman[21056]: Copying blob sha256:2c7ee7bc69e85f0517dccf3edfa293c2bfc147e3794ab403fda249c2e59a58ab
Nov 12 05:49:59 ip-10-2-40-39 podman[21056]: Copying blob sha256:028554d3b6ccc72641ab3b2a68597bf04cdbb49e03bb977c69198fd35c098e87
Nov 12 05:50:02 ip-10-2-40-39 podman[21056]: Copying config sha256:87440f4e7f9e60607dc11a4f0590a1c69b3a1c075211df478e22b0c27fb263e6
Nov 12 05:50:02 ip-10-2-40-39 podman[21056]: Writing manifest to image destination
Nov 12 05:50:02 ip-10-2-40-39 podman[21056]: Storing signatures

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 Debian 11 server in this guide.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy