How to Install and Use Podman
In the video below, we show you how to install and use Podman
Docker is a very popular platform for containers but there’s one thing that concerns me about it…containers are run using the root account
Now the developers did make it possible to run containers using a non-root account, but that’s not part of the default installation process
So why not use another platform like Podman?
Well what sets Podman apart is that it’s daemonless and its default installation makes running containers more secure
And in this video we’ll go over how to install Podman and use it to run containers
Useful links:
https://podman.io/docs/installation
Installation
Installing Podman on a Debian distro is as simple as it gets , but it’s best to first update the package repository cache
sudo apt update
sudo apt install podman -y
Although the instructions don’t mention it, I suggest rebooting the computer
sudo reboot now
If you don’t you’ll probably get error messages like this when you try to use Podman commands:
“The cgroupv2 manager is set to systemd but there is no systemd user session available”
Run Containers
Using Podman is very similar to what you do with Docker
For example, to run Apache in a container we can run a command like this
podman run -d -p 8080:80/tcp --name webserver docker.io/library/httpd
This will download the image for the httpd server, aka Apache web server, and run it in a container in the background on the familiar port 8080
And then we can check if it’s working using a web browser, or do a basic check on the computer using this command
curl http://localhost:8080
You can check which containers exist with this command
podman ps -a
To stop a container we can run this command
podman stop webserver
Hopfully, you’re now noticing the similarity with Docker
Security:
Now as I mentioned in the intro, one of the concerns with Docker is that with a default installation, containers are run using the root account
Now you might notice various documentation out there about how to set up Podman to run rootless containers
What we’ve done here though is just a default installation
First, lets start our web server back up
podman run -d -p 8080:80/tcp --name webserver docker.io/library/httpd
Now as you’ll see we run into a problem because a container has already been run with the name we’ve specified
You don’t get this issue with Docker I’ve noticed, but for Podman we need to clear unused containers
podman container prune -f
Next we’re going to check what user is running this container
ps aux
As you can see, our webserver isn’t being run by root
NOTE: The first line of reference will likely mention the user account you’re logged in with, others will show up with just a number. This is because an account has a range of IDs it can use
We can also check what is being run with the root account for extra measure
ps -u root
Before we move on, we’ll stop this container
podman stop webserver
Then clear unused containers to avoid future warnings and errors
podman container prune -f
Podman Compose:
Like Docker, you may prefer to manage your containers from a file
To do that, we’ll first install podman-compose
sudo apt install podman-compose -y
As with Docker, we need to create a compose file
nano compose.yaml
TIP: It does recognise other filenames
For our Apache server we’ll add this
version: '3'
services:
webserver:
image: docker.io/library/httpd
container_name: webserver
ports:
- '8080:80'
restart: unless-stopped
Now save and exit
So basically it’s the same as for Docker because compose files are based on a standard
Then to start up any containers defined in the file, we’ll run this command
podman-compose up -d
In other words, we want to start up any containers that aren’t yet running, but in the background
Podman Build:
Just like with Docker you can build your own images, which is the recommended way to deploy containers
In this example, we’ll create an Apache web server image, so first we’ll create a folder and switch to it
mkdir myapache_image
cd myapache_image
Next we’ll create the dockerfile
nano Dockerfile
NOTE: With Podman the file must be capitilised, otherwise you’ll get an error message
Then we’ll provide the instructions
FROM httpd:latest
COPY ./public-html/ /usr/local/apache2/htdocs/
Now save and exit
For our image, we’ll use the Apache web server as our base image, but replace the webpage using the COPY command to upload our own content
As we need to provide our own webpage for this, we’ll create a sub-folder
mkdir public-html
Then create our webpage in that folder
nano public-html/index.html
But we’ll keep this web page simple
<html><body><h1>This Is My Web Server!</h1></body></html>
Now save and exit
We’ll then build the image
podman build -t myapache .
You can check what images you have by running this command
podman images
Before we can use this image in a container, we’ll stop the other one
podman stop webserver
And clear out unused containers
podman container prune -f
Now we’ll run a container using the image we just built
podman run -d -p 8080:80/tcp --name myapache myapache
Finally, we can check if it’s working using a web browser, or do a basic check on the computer using this command
curl http://localhost:8080
NOTE: You can’t run two applications or containers in this case on the same host port, hence why the original container was stopped. They containers can still use port 80 themselves, but the host would have to map one to port 8080 and another to 8081 for instance
Privileged Ports:
Although we have the security benefit of Podman running containers rootless, there’s a problem if you want to use ports below 1024
For instance, lets say we want our web server to be available on port 80
After all, most users aren’t used to having to add a port number in the URL
Well first we’ll switch back to the parent folder, stop our container, then remove unused containers
cd ..
podman stop myapache
podman container prune -f
Next we’ll tell Podman to use port 80 instead of 8080
podman run -d -p 80:80/tcp --name myapache myapache
As you see, we get an error message
This is a downside of running containers rootless, they can’t use ports below 1024
There are different ways to deal with this, but we’ll add a new file to the /etc/sysctl.d/ folder
TIP: We could update the /etc/sysctl.conf file, as the error suggested, but that could change in a future update
sudo nano /etc/sysctl.d/98-containers.conf
net.ipv4.ip_unprivileged_port_start=23
Now save and exit
I’ve set the lower limit to 23 as SSH uses port 22 and I don’t want to run into a possible overlap in future and not being able to get access to the host
For the changes to take effect we need to reload the configuration
sudo sysctl --system
TIP: You can do the same for Docker if you want to run that rootless
You should see the port change in the output, but you can check with this command
sudo sysctl -a | grep "net.ipv4.ip_unprivileged_port_start"
Here we’re filtering out the parameter settings to just see information about what the lower port limit is
We’ll first stop our container
podman stop myapache
Then because Podman seems to be more fussy than Docker, remove unused containers
podman container prune -f
And then run our container again
podman run -d -p 80:80/tcp --name myapache myapache
Finally, we can check if it’s working using a web browser, or do a basic check on the computer using this command
curl http://localhost
The change does survive a reboot, so unless you need to lower the port level in future, no further changes should be necessary
Before we move on though, we’ll stop this container and clear unused containers
podman stop myapache
podman container prune -f
Manually Update Images:
Usually you’ll want to use the latest version of an image
And when you first run a container and ask for the latest version, the latest version will be download
Over time that image will become out of date though, so you’ll want to update it
You can find out what images are on your computer by running this command
podman images
If a container is running an image you want to update, you’ll want to stop it first, for example
podman ps
podman stop webserver
To manually update a specific image you can run a command like this
podman pull docker.io/library/httpd
Or if you’re using podman-compose you can use this command to update the images mentioned in a compose file
podman-compose pull
But again, you do need to stop the containers before updating the images
Podman Service:
The main appeal of Podman is that it runs containers using a non-root account
But that comes at a cost, because when the computer reboots your containers aren’t automatically started
To resolve this you need to create a service to run your Podman containers
Now how you do this depends on how you’re running your containers
A service for each individual container doesn’t seem practical to me, so either a script could be used or in this example we’ll run podman-compose
First we’ll create a new user account
sudo useradd -m -s /bin/bash podmanuser
The we’ll switch to that user account and switch to the home directory
sudo su podmanuser
cd
Next we’ll re-create our compose.yaml file to define our containers
nano compose.yaml
version: '3'
services:
webserver:
image: docker.io/library/httpd
container_name: webserver
ports:
- '8080:80'
restart: unless-stopped
Now save and exit
We’ll now switch back to our normal account
exit
Next we’ll create the service file
sudo nano /lib/systemd/system/podman-compose.service
[Unit]
Description=Podman-compose
Wants=network-online.target
After=network-online.target
[Service]
User=podmanuser
Group=podmanuser
Type=oneshot
RemainAfterExit=true
ExecStartPre=/usr/bin/podman system prune -f
ExecStart=/usr/bin/podman-compose -f /home/podmanuser/compose.yaml up -d
ExecStop=/usr/bin/podman-compose down
[Install]
WantedBy=default.target
Now save and exit
To tray and avoid problems, we’ll have Podman clear any used data first, in case there isn’t a clean shutdown for instance
The it will run podman-compose to bring up the containers
When the service is shutdown, it will tear down the containers
As we’ve created a new service, we’ll update the system, enable it to start on boot and then start the service
sudo systemctl --system daemon-reload
sudo systemctl enable podman-compose.service
sudo systemctl start podman-compose.service
Bear in mind, it does take a while to start the service for the first time because it will have to download the image(s)
This is because Podman is used on a per user basis and each user has their own storage area
But once we’re returned to the prompt, we can check if it’s working using a web browser, or do a basic check on the computer using this command
curl http://localhost:8080
One final check will be to reboot the computer and check again
sudo reboot now
Summary:
Hopfully as you can see, it’s relatively easy to setup and run rootless containers using Podman
The catch is if you’re only using Podman to run containers, and you want these to survive a reboot for instance
Then you’ll want to setup a service account to automatically start them
Now if you prefer to use a graphical user interface over a CLI to manage containers, then you can install Podman Dekstop to do that
One thing I haven’t touched on mind, and something you may want to explore, is Podman also allows you to group containers into a pod
So aside from the security benefits, and the simpler installation process, I think that’s another benefit that Podman has to offer over Docker
Sharing is caring!