Running Ubuntu with Podman


#1

Introduction

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.

Glossar

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 http://hub.docker.com 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/egon/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/egon/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:

root@d61c9266373d:/#

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
chown -R 700 /home/egon
chmod -R egon:users /home/egon

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  docker.io/library/ubuntu:19.04  /bin/bash  4 minutes ago  Exited (0) 4 seconds ago         mycontainer
9a8d31421558  docker.io/library/ubuntu:18.04  /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  docker.io/library/ubuntu:19.04  /bin/bash  7 minutes ago  Up 3 seconds ago         mycontainer
9a8d31421558  docker.io/library/ubuntu:18.04  /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 egon --workdir /home/egon 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:

#!/bin/bash

CONTAINER=mycontainer

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

xhost +
podman exec --interactive --tty --user egon --workdir /home/egon $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:


Como instalar librecad?
No network in toolbox container
#2

Hallo Egon, thanks a lot, very nice tutorial.

Just curious: I experimented a little bit with three different debian based containers (docker.io/library/neurodebian:latest, docker.io/tianon/wine:latest, and docker.io/library/debian:stable-slim) 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?


#3

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.


#4

once again: thanks for the tutorial and the assistance.