Skip to content

podman

This article showcases how I use Podman to run services that I use daily. These services are available as hosted web solutions, which I want to avoid leveraging as I use them to create content for my customers. Privacy first! These services can be self-hosted on a remote machine accessible via the Cloudflare Wrap method or just running on your laptop on the go.

Why Podman? It is 100% open source, no daemon, rootless, available from your Linux package system, Kubernetes friendly, and compatible with all the legacy builts made using Docker. It requires about 20 minutes of usage to fully comprehend the reason for switching from Docker to Podman. There is also an excellent Podman Desktop option.

Let's explore Podman via some examples.

draw.io

draw.io is one of my favorite tools. It allows me to quickly sketch diagrams and architecture during a meeting or a call, and it's open source!

deploy

Pull the image:

podman pull jgraph/drawio

Output:

romdalf@alps:~$ podman pull jgraph/drawio
✔ docker.io/jgraph/drawio:latest
Trying to pull docker.io/jgraph/drawio:latest...
Getting image source signatures
Copying blob d66d6a6a3687 done   | 
Copying blob 327a048589de done   | 
Copying blob f0c59d8a84db done   | 
Copying blob 5e3f591e1537 done   | 
Copying blob f0374c36aa38 done   | 
Copying blob dc4b0bb2324f done   | 
Copying blob 0b8d46dcb3f0 done   | 
Copying blob 3ef4bb1257ac done   | 
Copying blob 5b7fd70fc1f9 done   | 
Copying blob e08731b65eba done   | 
Copying blob 00bc11350f97 done   | 
Copying blob eddb9a5976b9 done   | 
Copying blob 79280d37efa5 done   | 
Copying blob 4f4fb700ef54 done   | 
Copying blob 2414c1f7a801 done   | 
Copying blob 4f4fb700ef54 skipped: already exists  
Copying config eea29c1753 done   | 
Writing manifest to image destination
eea29c1753d33ebeb6890f4bab463916d500923baa1eb8cc99434ebbfd793b4c

Start the container:

podman run --name draw.io --detach --rm --publish 8080:8080 --publish 8443:8443 jgraph/drawio:latest
Output:
romdalf@alps:~$ podman run --name draw.io --detach --publish 8080:8080 --publish 8443:8443 jgraph/drawio:latest
4bd81e7ab7396fab19608748dcc225138c6fe77ca1ca8f2773ed8e98b5fb8cf0
Check the status:
podman ps
Output:
romdalf@alps:~$ podman ps
CONTAINER ID  IMAGE                           COMMAND          CREATED        STATUS        PORTS                                           NAMES
4bd81e7ab739  docker.io/jgraph/drawio:latest  catalina.sh run  9 seconds ago  Up 9 seconds  0.0.0.0:8080->8080/tcp, 0.0.0.0:8443->8443/tcp  draw.io

Note: If you don't see the container in the list, try podman ps —a``. If the container is present, it means that it fails to start. In that case, run the container without the--detach``` flag to grab the error message.

At this stage, you can open the URL 127.0.0.1:8080 or :8080 to start a draw.io session.

systemd

Interestingly, the start/stop of containers can be associated with systemctl and user login. If you wish to have this service start at user login, you can do the following:

Generate the systemctl files:

podman generate systemd --name draw.io --files --start-timeout=180 --stop-timeout=180
A service file, /home/romdalf/container-draw.io.service in this case, will be created within the current folder with the following content:
# container-draw.io.service
# autogenerated by Podman 4.9.3
# Wed Mar  6 16:36:32 CET 2024

[Unit]
Description=Podman container-draw.io.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/run/user/1000/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStartSec=180
TimeoutStopSec=240
ExecStart=/usr/bin/podman start draw.io
ExecStop=/usr/bin/podman stop  \
        -t 180 draw.io
ExecStopPost=/usr/bin/podman stop  \
        -t 180 draw.io
PIDFile=/run/user/1000/containers/overlay-containers/25123dda8fe30ea9d1f141b6a0fb542b258b0048d76270b731a422fe0bba8457/userdata/conmon.pid
Type=forking

[Install]
WantedBy=default.target

Enable the user level systemd with:

systemctl --user enable ./container-draw.io.service
Output:
romdalf@alps:~$ systemctl --user enable ./container-draw.io.service
Created symlink /home/romdalf/.config/systemd/user/container-draw.io.service → /home/romdalf/container-draw.io.service.
Created symlink /home/romdalf/.config/systemd/user/default.target.wants/container-draw.io.service → /home/romdalf/container-draw.io.service.

Note: To keep things tidy, you can create a directory called podman-services and copy all your service files in.

Stop your running container:

podman stop draw.io
Start it with systemd:
systemctl --user start container-draw.io.service
Check if the container is started with systemd:
systemctl --user status container-draw.io.service
Output:
romdalf@alps:~$ systemctl --user status container-draw.io.service 
● container-draw.io.service - Podman container-draw.io.service
     Loaded: loaded (/home/romdalf/.config/systemd/user/container-draw.io.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/user/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Wed 2024-03-06 16:38:28 CET; 11min ago
       Docs: man:podman-generate-systemd(1)
    Process: 46983 ExecStart=/usr/bin/podman start draw.io (code=exited, status=0/SUCCESS)
   Main PID: 47019 (conmon)
      Tasks: 16 (limit: 34698)
     Memory: 5.2M
        CPU: 126ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/container-draw.io.service
             ├─46998 /usr/bin/slirp4netns --disable-host-loopback --mtu=65520 --enable-sandbox --enable-seccomp --enable-ipv6 -c -r 3 -e 4 --netns-type=path /run/user/1000/netns/netns-2f821640->
             ├─47000 rootlessport
             ├─47006 rootlessport-child
             └─47019 /usr/bin/conmon --api-version 1 -c 25123dda8fe30ea9d1f141b6a0fb542b258b0048d76270b731a422fe0bba8457 -u 25123dda8fe30ea9d1f141b6a0fb542b258b0048d76270b731a422fe0bba8457 -r />

When you log in or out, your container will start or stop.

Note: If you are using a workstation that stays up and running, you can change this behavior with the following command:

loginctl enable-linger <username>
Then, the logout procedure will not stop your container.

volumes

As per the nature of containers, local storage is required to store the data related to the related services. There are multiple ways to address these needs:
* creating your folder tree * leveraging volumes

We will do the latter to let Podman deal with most behind-the-scenes work with Linux.