Deep Dive - How To Install Podman and Setup Quadlets (Rootless Guide)
Podman is a very popular container platform because it makes it much easier to run non-root containers
This is a big deal from a security perspective because in theory, if a container is compromised and the attacker gains access to the operating system, they can do whatever the user running the container can do
So unless there’s a software bug, an account can’t then be given elevated privileges
The SSH server can’t be replaced, a keylogger can’t be installed, the firewall rules can’t be changed, and so on
And thanks to a feature known as Quadlets, it’s much easier for non-root users to run their containers as a service
But how do you install Podman on a Debian based computer for instance, and how do you setup Quadlets?
Install Podman:
Well how you install Podman depends on the operating system you’re using
For this video we’ll be using Debian 13, although there are lot of distros out there based on Debian
Granted, I won’t get access to new Podman features until Forky is released, but I prefer stability over bleeding edge technology
Having said that, Quadlets is a feature of Systemd, so there are more operating systems you can use
And lately for example, I’ve been demonstrating Quadlets using Fedora CoreOS in videos for Lab Members
Now because Debian uses APT, the first thing to do is to update our package information
sudo apt updateIn other words, we want to make sure we get the latest package update
Next we’ll install Podman
sudo apt install podman -yWe’ll then do a simple test to make sure Podman is working
podman run hello-worldCreate User:
Now running containers with the user account we currently have would defeat the main benefit of Podman as this account can run commands with elevated rights
In which case, we’ll create another user account to run containers with
sudo useradd -m -s /bin/bash poduserWhile this account will have a home directory to store files in and will use the bash shell, I’m not going to give it a password because I don’t want anyone to login as this user
That’s because I prefer to use Ansible to do everything and I’ll only have to concern myself with the Ansible account when it comes to authentication
The main appeal of Quadlets is when you have a team of users who’ll be logging into the server and creating containers
Previously they couldn’t create service accounts and relied on someone with elevated privileges to do that for them
With Quadlets they can manage their own non-root services
And while what I’m doing does somewhat limit the gains of Quadlets, because a super user can create services and run them with a non-root account anyway, this makes it less likely I’ll run a container as root by mistake
Now despite their original purpose, containers are typically running 24x7 when they’re being used to sandbox applications
In that situation, a container needs to be automatically started again if the computer reboots or is started up from cold
But you don’t want to be forced to wait for the user to login for a service to start
In which case, lingering needs to be enabled for the user account
sudo loginctl enable-linger poduserWith that done, I can then switch to that non-root account and start using Podman
Now in previous videos you’ll have seen me do something like this
sudo su poduserI used to do something similar when switching to root, but as was pointed out to me it was incorrect
In other words, the sudo command has evolved over the years and it doesn’t rely on the su command to allow you to switch user accounts
The better option for switching to a user account is to do this
sudo -i -u poduserThis makes sure we’ll have the proper user environment and that’s very important for what we want to do
Quadlets:
Because Podman doesn’t normally use a daemon to manage and monitor your containers, if a computer is rebooted or starts up from cold, any container you’ve created won’t be automatically started
So typically when you use Podman, you run containers using a service so it starts as part of the bootup process and that’s what we’re doing with Quadlets
Now before we get started, I will say that Quadlets can take a bit of getting used to, especially if you’ve already created services using Systemd
The differences may be minor, but are easily forgotten
In this example we’ll create a basic nginx container, so first we’ll create a folder to store website pages in
mkdir -p nginx/my-websiteThen we’ll create a simple home page
echo '<h1>Nginx is working!</h1>' > nginx/my-website/index.htmlWhen it comes to Quadlets, each user has their own special folder to store them in, so we’ll create that
mkdir -p .config/containers/systemd/Now we’ll create a Quadlet to run nginx with
nano .config/containers/systemd/nginx.container[Unit]
Description=Rootless Nginx Web Server
After=network-online.target
[Container]
Image=docker.io/nginxinc/nginx-unprivileged:latest
PublishPort=8080:8080
Volume=%h/nginx/my-website/:/usr/share/nginx/html:ro
[Service]
Restart=always
[Install]
WantedBy=default.targetNow save and exit
Basically this looks like any other service file, the difference being the Container section
So this one will use an unprivileged nginx image, listen on port 8080 and map the webpage folder to the container
Next, we need to declare some variables otherwise when we try to setup the service it will fail
One way to do this is to update the .bashrc file
cat << 'EOF' >> ~/.bashrc
if [ -z "$XDG_RUNTIME_DIR" ]; then
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus
fi
EOFIn other words, we want these present in all of our sessions
TIP: Rather than logging out and logging back in, you can reload the file
source ~/.bashrcBecause we’ve made a service change, we need to update the daemon
systemctl --user daemon-reloadNote the use of –user as a parameter as this can easily trip you up
Next we’ll start the service and thus the container
systemctl --user start nginxBear in mind, we don’t need to enable a service for a non-root user, we just need to start it. If you do try to do that it will return an error
It may take a while to return to the prompt because there is no feedback, and the computer has to download the image if it isn’t already there
We can then check the website is working by running this command
curl http://localhost:8080If you want to check the service itself, you’ll want to run this command
systemctl --user status nginxUnfortunately as a non-root user you can’t check the service logs, but you can still check container logs
First we need to find the name of the container
podman psHere we see it’s prepended with systemd-
Now we’ll check it’s logs
podman container logs systemd-nginxYou can still usually run other podman commands but bear in mind the container is now managed as a service
Lines in config files mapped to a container can be changed and the container can also be restarted as normal for instance
But if changes are made to the container definition itself then this requires a service change
For example, if you need to change the listening port, you’ll edit the nginx.container file in this case
You’ll then need to stop the service to stop the container
systemctl --user stop nginxNext you’ll reload the daemon and start the service
systemctl --user daemon-reload
systemctl --user start nginxAs a final check, it would do well to reboot the computer after you create your first Quadlet, but don’t login to the server running Podman
This is to check your containers will survive a reboot for instance and can continue running without user intervention
Summary:
For non-root users, Quadlets are extremely useful because you don’t rely on an Admin to create a service account for you
Instead you can create whatever containers you like that can survive reboot
Well, as long as Linux allows a port to be used and it isn’t already in use by another container that is
Sharing is caring!