Docker -> Podman + Quadlet
Containers are light-weight virtual machines, often used to run isolated services on a server. They (typically) use the host kernel and don’t virtualise resources, leading to higher performance with minimal overhead compared to traditional virtual machines (like qemu).
Docker is the most widely used container engine, and has been at the head of the industry for a while. It uses a daemon run by the root user to start its containers. This has long been a security concern, as a malicious entity that breaks out of the container will have root access to the system!
Podman, a tool developed by Redhat, is quite similar to docker but crucially doesn’t require a daemon to run. This means unprivileged users can still get the benefits of containerization! Docker has recently been experimenting with a similar “rootless mode”, but it’s not nearly at feature parity. Further, since Podman is developed by Redhat, it integrates with other Redhat projects very nicely, like systemd, nftables, and cockpit.
Summary
In this blog, we’ll look at migrating an existing Docker Compose service to Podman! We’ll cover setting up our new Podman service with systemd’s Quadlet integration with a new unprivileged user.
Prerequisites:
- A computer with linux (root access required, if you want to make a new user)
Optional:
- Root access, if you’d like to make a new user
- An existing Docker Compose service. You can use the one in this tutorial too
I’m using archlinux for this example, but any systemd-based linux will work (Ubuntu, Debian, Fedora, Redhat…). You might need to change a few of the user-creating commands on other systems.
Creating a New User
We will assume 2 users:
emily
is an existing sudoer who’s running a Docker Compose servicekate
will be a new unprivileged user who will run our Podman Quadlet
Start by logging into root
and setting up kate
(optional if you want to use
emily
to host your Quadlet):
For Podman, we’ll need to give kate
a range of sub-ids, which the container
can use to differentiate users, while still all being kate
:
Assuming we don’t typically use the kate
user, we also want to make sure our
containers aren’t killed once we logout of kate
:
Podman is also quite sensitive to XDG environment variables. Make sure you have them setup properly. For example:
Now to make sure that worked:
Migrating Docker Compose to Podman + Quadlet
Consider this docker-compose.yml:
We could covert this to a simple Podman bash script. It’s a good idea to try
this step as kate
before proceeding. Notice that kate
will need her own
./data
directory. Try running this as kate
:
A Quadlet file is similar to a systemd unit file, but describes the same things as a docker-compose.yml:
In this case, I put my Quadlet file at
/home/kate/Documents/servers/openwebui/openwebui.container
. I put a
corresponding /home/kate/Documents/servers/openwebui/data
directory to mount
in the container.
See Erick Patrick’s repository for a great Quadlet template with all the important options!
Quadlet files for a user should be at ~/.config/containers/systemd/
. To be a
bit more organized, we’ll simply symlink our container out of
~/Documents/servers
to here:
Running Quadlets
Use kate
to test if our Quadlet is working:
/usr/lib/podman/quadlet -dryrun -user
This should print out a file it calls openwebui.service
. It looks similar to
our openwebui.container
, but added more to the [Service]
section and added a
[X-Container]
section. Quadlet essentially converts our .container
files to
systemd .service
files, so that systemd can run them normally. Let’s try it!
Refresh your daemon:
Now check the status:
We can start it just like any other systemd service:
Then, the analog to docker log
is journalctl --user -fu openwebui.service
!