Use Ubuntu and other distributions as Docker containers

Cleanly Docked

Article from Issue 268/2023

Do you work with Ubuntu but want to test something quickly on an openSUSE system? You don't need a second PC or a virtual machine to do it – a single container is quite enough.

A virtual machine (VM) lets you use software intended for a different Linux distribution or even a different operating system. But setting up a VM can be time consuming. If you use VirtualBox, VMware [1], or Gnome Boxes [2], you can configure and start a virtual PC in the program interface before proceeding with the regular operating system install. After completing this procedure, the window will contain a full graphical desktop, such as KDE or Gnome, and you can boot and shut down the VM like a real PC.

In many cases, a full install is exactly the solution you need, but sometimes you may just want to quickly test a program. Then the overhead for a VM install of a complete system is disproportionate to the results. The reasons why you cannot always run programs directly on your Linux system are revealed in the "Library Dependencies" box.

Library Dependencies

The reason why you cannot run arbitrary Linux applications on just any system is that the program files usually contain only parts of the binary code that the computer executes. Much of the functionality is found in library files that Linux additionally loads at program startup time. For example, if an interactive program in text mode wants to read a line of text, it does not use its own routine for this, but instead resorts to the readline function from the library of the same name. Figure 1 shows a small sample program that reads a line of text and outputs it unchanged with a hint. The code for the input and output comes from the readline library function for the input and from printf for the output. When compiling with GCC, the -lreadline option ensures that the compiler notes the dependency on the readline library in the generated program file.

Figure 1: Using what others have developed. Thanks to library functions such as readline, you don't have to constantly reinvent the wheel.

The last command in Figure 1 shows all the libraries that the test program needs, including The file extension .so.8 indicates that the program expects a specific version of the library, version 8. If you try to run the program on a machine with the older readline version 6 or 7, the program loader will fail to find the library and will complain (Listing 1). Missing libraries can be installed later on: Linux is quite flexible and lets you install different versions of the same library at the same time. Whether you will find a missing version for a particular Linux distribution is another question.

There is so much dynamism in Linux and the applications available for it that each distribution update also updates a few library packages. Programs that require libraries that are too new or too old will no longer run. Switching to a different distribution, such as from Ubuntu to openSUSE, becomes even more difficult because distributors often decide for themselves to keep certain software packages at a version below the latest available one. A program compiled for openSUSE might then need libraries from two different releases on Ubuntu.

Listing 1

Version Error

./readline-test: error while loading shared libraries: cannot open shared object file: No such file or directory

If you develop your own software, you may want to test whether the program files you generate will run on all distribution versions you support. Can the RPM or Debian package you generated be installed? Are all dependencies on libraries met so that the program actually launches? Finally, does it work as expected? Again, using a VM is a little excessive for these software tests.

Containers offer an alternative to VMs or real hardware: They do not virtualize a complete computer and are therefore not suitable for all purposes, but in many cases they are perfect for the use case at hand. The advantage they have is that of resource efficiency (lower RAM and disk space requirements), and they can be set up far faster than a VM. You can deploy a new container in seconds, while a fresh installation in a VM will take around 15 minutes. Even when cloning an existing VM, you can expect a wait of several minutes because multiple gigabytes of data need to be copied in the process.

This article takes a look at Docker [3]. But there are other tools for providing containers on Linux. Docker competitor Linux Containers (LXC [4]) is another popular choice; it is used, for example, by the Proxmox [5] VM and container management tool.

Installing Docker

Docker is quickly set up. On Ubuntu, install the package (Listing 2, line 2) and sign up as a member of the new docker group using usermod (line 3). On an openSUSE system, you can install with Zypper (line 5). The package there is simply named docker, and the Docker service is still disabled after the setup. You can change this with the two systemctl calls (lines 6 and 7).

Listing 2

Setting Up Docker

01 ### On Ubuntu
02 $ sudo apt install
03 $ sudo usermod -a -G docker esser
04 ### On OpenSuse
05 $ sudo zypper install docker
06 $ sudo systemctl enable docker
07 $ sudo systemctl start docker
08 ### Function test
09 $ docker run hello-world

Log out and then log back in for your new group membership to take effect. By the way, in our test on Ubuntu 22.04, a new login was not enough. We had to kill all of our own processes by typing

sudo killall -9 -u $USER

and then log in again for this to work. Alternatively, you could reboot the computer, but the killall approach is faster.

Finally, make sure the setup worked (line 9). The program should output a few lines of text, including Hello from Docker!. If the test fails, use groups to check if you are a member of the docker group. Also use systemctl status docker to see if the Docker daemon is running.

Images and Containers

Running the Docker run hello-world command from line 9 of Listing 2 downloaded an image from Docker Hub [6], created a new container from the image file, and started the container. The container then ran a Hello World program that printed all the lines in the output starting at Hello from Docker.

If you are new to containers, the terms "image" and "container" might be confusing. An image is essentially a collection of files, supplemented by various metadata, such as the computer architecture or specifications for environment variables. It only acts as a template for creating a container. When you run the docker run <image> command, Docker creates a container from the specified image file. To do this, the tool unpacks the image. You will find the files in a subfolder of /var/lib/docker/overlay2/.

Docker then launches a program from that folder, pretending that the folder is the root filesystem. The program cannot access files located farther up in the filesystem, which protects your normal Linux system against manipulation attempts from inside the container. Besides being locked into a subfolder, far more happens. Among other things, the container has its own network settings, which are independent of the host system.

You can use a single image file to create multiple containers in which separate processes then run. The containers change at runtime because you can delete, recreate, or edit files in them. If you are looking for an analogy for the difference between images and containers: Compared with virtualizers such as VMware and VirtualBox, an image would correspond to a virtual appliance, while the container would correspond to the individual VM.

Disposable Containers

Containers (unlike VMs) are often used just once. In this case a single command runs the container, and Docker immediately deletes it afterwards. Docker comes with a --rm option, which automates the delete process.

This wasteful use of containers is possible (and makes sense) because creating and deleting containers is virtually effortless. It is only when you launch a container for the first time that you need to obtain the matching image, typically from Docker Hub [6]. On all subsequent launches, it will already exist in Docker's local cache directory.

Because containers are often short-lived, it has become common practice to store configuration files and anything else that you want keep outside the container. To do this, you can either make part of the normal filesystem available in the container or create special container volumes.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Docker Open Source Developer Tools

    Docker provides the open source tools and resources for compiling, building, and testing containerized applications.

  • Tutorials – Docker

    You might think Docker is a tool reserved for gnarly sys admins, useful only to service companies that run complicated SaaS applications, but that is not true: Docker is useful for everybody.

  • Docker with OwnCloud

    Run your application smoothly and portably in the cloud with the Docker container system. This workshop takes a practical look deploying Docker with the OwnCloud cloud environment.

  • Perl: Testing Modules with Docker

    If you want to distribute your programs across multiple platforms, you need to prepare them to run in foreign environments from the start. Linux container technology and the resource-conserving Docker project let you test your own Perl modules on several Linux distributions in one fell swoop.

  • Docker

    Docker is an economical alternative to conventional virtualization. Because each Docker container shares the underlying operating system, it enjoys the resource isolation and allocation benefits of VMs but is much more portable and efficient.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More