Running Ubuntu with Podman


What is this all about?

Podman is a technology, which allows you to run an arbitrary linux operating system inside something called a “container”. A “container” can be seen as a operating system, running inside another operating system like an application.


Podman: The technology and also the main command used here (podman)
Container: A isolated operating system running as an application and sharing resources with the host system
Image: An operating system image used to run inside a container

Whats the difference to Toolbox?

Toolbox is something like a convenience wrapper around the Podman technology which makes your life easier, but also more restricted. It’s like a golden cage.

Getting started

Download the needed images

podman image pull ubuntu:19.04

This will fetch the current stable release of Ubuntu. If you omit :19.04, you will get the latest LTS Version, which is 18.04 at the time.

To show all the images you have downloaded already, use:

podman image list --all

There are many more different images available, just visit if you need anything else - there are also preconfigured images for various needs available.

Creating something like a share

I personally like to keep my home directory clean, so i don’t like Toolbox’s approach of mapping the entire home directory into the container. We will create a new directory which we use exclusively for sharing files with the container.

mkdir ~/sharing

Create your first container

podman run --interactive --tty --name mycontainer --volume /tmp/.X11-unix:/tmp/.X11-unix \
--env DISPLAY --device /dev/dri --device /dev/snd --device /dev/input \
--volume /etc/localtime:/etc/localtime:ro --volume /sysroot/home/$(whoami)/sharing:/mnt ubuntu:19.04

This will create the container and open a terminal inside this container for doing your first configuration work. But at first, let’s take a look at the parameters:

Parameter Meaning
run Create the container and also run it immediatly
–interactive Open a terminal for the newly created container
–tty Allocate a new pseudo terminal inside the container, e.g. open stdin and stdout
–name mycontainer Give the container a meaningful name
–volume /tmp/.X11-unix:/tmp/.X11-unix Map the X11 Socket into the Container for X11 Access
–env DISPLAY Set the DISPLAY environment variable inside the container for every interactive session
–device /dev/dri Allow access to the DRI Device to provide HW accelerated 3D
–device /dev/snd Allow access to the Audio Device
–device /dev/input Allow access to Input Devices like Gamepads
–volume /etc/localtime:/etc/localtime:ro Map /etc/localtime to give the container the same time as the host
–volume /sysroot/home/$(whoami)/sharing:/mnt Map our created share to /mnt inside the container
ubuntu:19.04 The image to use

Networking should work out of the box, as podman created a bridge on the default network interface by default. Immediatly after creation, you should have a prompt like:


Now you can do various tasks like creating a user for you to use:

useradd  -d /home/egon -s /bin/bash egon
mkdir -p /home/egon
chmod -R 700 /home/egon
chown -R egon:users /home/egon

Replace egon with your username and leave this session by typing exit

Managing your container

To verify if your container has been created successfully, use the command:

podman container list --all

This will give you something like:

CONTAINER ID  IMAGE                           COMMAND    CREATED        STATUS                    PORTS  NAMES
d61c9266373d  /bin/bash  4 minutes ago  Exited (0) 4 seconds ago         mycontainer
9a8d31421558  /bin/bash  5 days ago     Created                          test

Note here the state of the container, which is in my case “Exited”. After exiting the initial shell, the container is stopped. We have to manually start the container once before we can use them - until the reboot of our host:

podman start mycontainer

… and verify if it’s really running with:

podman ps --all

… will give you:

CONTAINER ID  IMAGE                           COMMAND    CREATED        STATUS            PORTS  NAMES
d61c9266373d  /bin/bash  7 minutes ago  Up 3 seconds ago         mycontainer
9a8d31421558  /bin/bash  5 days ago     Created                  test

Using the container

Now that we have a running container, we want to do something with it. At first, open up a session inside the container:

As the use we created before:

podman exec --interactive --tty --user $(whoami) --workdir /home/$(whoami) mycontainer /bin/bash

As root:

podman exec --interactive --tty mycontainer /bin/bash

Use this session for any task you want :slight_smile: A good idea is to open a root shell and update everything:

apt-get update; apt-get -y dist-upgrade

Removing the container

Containers need to be stopped in order to remove them:

podman stop mycontainer
podman rm mycontainer

Nothing is left behind.

Making it more convenient

I use the following shell script to run my container:



podman ps | grep $CONTAINER 2>/dev/null 1>&2
if [ $? -ne 0 ]; then
	podman start $CONTAINER

xhost +
podman exec --interactive --tty --user $(whoami) --workdir /home/$(whoami) $CONTAINER /bin/bash

At first, it will check if the container is running and start them if needed. Then it will instruct our host to allow X server connections and fire up a session in the container with my user.

Solving Problems

One common issue is with updating the files inside the container. For example, updating systemd will always be problematic and lead to various problems with APT. This mostly occurs with packages which have a deep system houskeeping and are not necessary within containers (because those things are managed by the host)

To prevent such packages from updating, you have to mark it. As root, execute the following commands:

apt-mark hold libsystemd0
apt-mark hold libsystemd0:i386
apt-mark hold systemd
apt-mark hold systemd:i386
apt-mark hold tzdata
apt-mark hold tzdata:i386

If you already did a apt-get dist-upgrade and the system is in a bad state, you have to force-remove the half-installed package with dpkg and install it manually. But in this case, write a reply and let’s do it together :slight_smile:


Hallo Egon, thanks a lot, very nice tutorial.

Just curious: I experimented a little bit with three different debian based containers (,, and and all three throw errors, when I try to apt upgrade (of course after an apt update):

dpkg: error processing archive /var/cache/apt/archives/tzdata_2019c-0+deb9u1_all.deb (–unpack):
unable to make backup link of ‘./usr/share/zoneinfo/UCT’ before installing new version: Invalid cross-device link
dpkg: error while cleaning up:
unable to restore backup version of ‘/usr/share/zoneinfo/Turkey’: No data available
dpkg: error while cleaning up:
unable to restore backup version of ‘/usr/share/zoneinfo/ROK’: Operation not permitted
dpkg: error while cleaning up:
unable to restore backup version of ‘/usr/share/zoneinfo/ROC’: Operation not permitted
dpkg: error while cleaning up:
unable to restore backup version of ‘/usr/share/zoneinfo/Portugal’: Operation not permitted
dpkg: error while cleaning up:
unable to restore backup version of ‘/usr/share/zoneinfo/Poland’: Operation not permitted
dpkg: error while cleaning up:
unable to restore backup version of ‘/usr/share/zoneinfo/Pacific/Wallis’: No data available

[… lots of similar cleanup errors not reproduced …]

No such errors occur for the Ubuntu 19.04 image.
Any ideas, what causes these errors?

1 Like

Long answer:
After doing a little research, it turns out, that /etc/localtime is a link to /usr/share/zoneinfo/… in Debian. As we are bind-mounting the host’s /etc/localtime read-only to it, the link becomes read-only in the container. In Ubuntu it’s not a link but a file.

Short answer:
Create the container without mounting /etc/localtime and you’re fine.

once again: thanks for the tutorial and the assistance.

this command is giving error:
chmod: invalid mode: ‘egon:users’

Please correct it. I am sorry I could not correct it myself.


Hi, replace every occurence of egon (which is my username) with $(whoami), which will yield your username. I updated the tutorial above too, to reflect this.

I knew this had replaced “egon” with the username(vidya) I wanted to create but I repeat that the command:
chmod -R vidya:users /home/vidya
is giving this error
chmod: invalid mode: ‘vidya:users’
Try ‘chmod --help’ for more information.

The error shows that it is taking ‘vidya:users’ as a mode and there may be syntax problem here.
Incidentally username vidya is not the same as username on Endless OS but I think this should not matter.


You are absolutely right. I mixed up the two commands, chmod and chown - the first one changes the permissions and expects a permission specifier as it’s argument, the later one changes the owner and expects a user and group combination. I updated the commands in the tutorial.

chown -R $(whoami):users /home/$(whoami)

… is the correct command.

Please add commands to create password for the user and enable sudo here.

As everything is running within your user context, you don’t gain any additional security by setting user and root passwords. If you want to change to the root user, simply use:

su -

or, open another Terminal window and simply execute a shell inside the container as root as described above.

[quote=“egrath, post:1, topic:10506”]
useradd -d /home/$(whoami) -s /bin/bash $(whoami)
[/quote]This command gives error:
useradd: user ‘root’ already exists

and we need to replace $(whoami) with username here in this and subsequent commands.

I use Gnucash to keep track of my expenses, assets, investments on daily basis. Endless OS came pre installed on my Acer Aspire3 Laptop and liked the OS but the Flatpak version of Gnucash did not have Finance:Quote Module and my investments were not getting updated.

I was looking for installing Gnucash version which has Finance:Quote and egrath suggested to use Podman. I could install Gnucash on Ubuntu 19.10 in a Container and I am happy that it is working.

Thank you egrath.


This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.