Now that the basics of Linux Containers have been covered in the previous chapter, this chapter will demonstrate how to create and manage containers using the Podman, Skopeo and Buildah tools on Ubuntu. It is intended that by the end of this chapter you will have a clearer understanding of how to create and manage containers on Ubuntu and will have gained a knowledge foundation on which to continue exploring the power of Linux Containers.
1.1 Installing the Container Tools
Before starting with containers, the first step is to install all of the container tools outlined in the previous chapter using the following commands:
# apt install curl # . /etc/os-release # sh -c "echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list" # curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add - # apt update # apt install podman skopeo buildah
1.2 Pulling a Container Image
For this example, the most recent Ubuntu release will be pulled from the registry. Before pulling an image, however, information about the image repository can be obtained using the skopeo tool, for example:
$ skopeo inspect docker://docker.io/ubuntu { "Name": "docker.io/library/ubuntu", "Digest": "sha256:bec5a2727be7fff3d308193cfde3491f8fba1a2ba392b7546b43a051853a341d", "RepoTags": [ "10.04", "12.04.5", "12.04", "12.10", "13.04", "13.10", "14.04.1", "14.04.2", "14.04.3", "14.04.4", "14.04.5", "14.04", "14.10", "15.04", . . ], "Created": "2020-03-20T19:20:22.835345724Z", "DockerVersion": "18.09.7", "Labels": null, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:5bed26d33875e6da1d9ff9a1054c5fef3bbeb22ee979e2acf72528de007b", "sha256:f11b29a9c7306674a9479158c1b4259938af11b979ac02030cc1095e9ed1", "sha256:930bda195c84cf132344bf38edcad255317380503fef234a9ce3bff0f4dd", "sha256:78bf9a5ad49e4ae42a83f4995ade4efc08fd38299cf05bc041e8cdda2a36" ], "Env": "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ] }
For example, to pull the latest Ubuntu image:
$ podman pull docker://docker.io/ubuntu:latest Trying to pull docker://docker.io/ubuntu:latest... Getting image source signatures Copying blob 5bed26d33875 done Copying blob f11b29a9c730 done Copying blob 78bf9a5ad49e done Copying blob 930bda195c84 done Copying config 4e5021d210 done Writing manifest to image destination Storing signatures 4e5021d210f65ebe915670c7089120120bc0a303b90208592851708c1b8c04bd
Verify that the image has been stored by asking podman to list all local images:
![]() |
You are reading a sample chapter from Ubuntu 20.04 Essentials. Buy the full book now in eBook ($14.99) or Print ($36.99) format. Includes 37 chapters. Learn more. |
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/ubuntu latest 4e5021d210f6 3 weeks ago 66.6 MB
Details about a local image may be obtained by running the podman inspect command:
$ podman inspect ubuntu:latest
This command should output the same information as the skopeo command performed on the remote image earlier in this chapter.
1.3 Running the Image in a Container
The image pulled from the registry is a fully operational image that is ready to run in a container without modification. To run the image, use the podman run command. In this case the –rm option will be specified to indicate that we want to run the image in a container, execute one command and then have the container exit. In this case, the cat tool will be used to output the content of the /etc/passwd file located on the container root filesystem:
$ podman run --rm ubuntu:latest cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin
Compare the content of the /etc/passwd file within the container with the /etc/passwd file on the host system and note that it lacks all of the additional users that are present on the host confirming that the cat command was executed within the container environment. Also note that the container started, ran the command and exited all within a matter of seconds. Compare this to the amount of time it takes to start a full operating system, perform a task and shutdown a virtual machine and you begin to appreciate the speed and efficiency of containers.
To launch a container, keep it running and access the shell, the following command can be used:
![]() |
You are reading a sample chapter from Ubuntu 20.04 Essentials. Buy the full book now in eBook ($14.99) or Print ($36.99) format. Includes 37 chapters. Learn more. |
$ podman run --name=mycontainer -it ubuntu:latest /bin/bash [email protected]:/#
In this case, an additional command-line option has been used to assign the name “mycontainer” to the container. Though optional, this makes the container easier to recognize and reference as an alternative to using the automatically generated container ID.
While the container is running, run podman in a different terminal window to see the status of all containers on the system:
$ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4b49ddeb2987 docker.io/library/ubuntu:latest /bin/bash About a minute ago Up About a minute ago mycontainer
To execute a command in a running container from the host, simply use the podman exec command, referencing the name of the running container and the command to be executed. The following command, for example, starts up a second bash session in the container named mycontainer:
$ podman exec -it mycontainer /bin/bash [email protected]:/#
Note that though the above example referenced the container name the same result can be achieved using the container ID as listed by the podman ps -a command:
$ podman exec -it 4b49ddeb2987 /bin/bash [email protected]:/#
Alternatively, the podman attach command will also attach to a running container and access the shell prompt:
![]() |
You are reading a sample chapter from Ubuntu 20.04 Essentials. Buy the full book now in eBook ($14.99) or Print ($36.99) format. Includes 37 chapters. Learn more. |
$ podman attach mycontainer [email protected]:/#
Once the container is up and running, any additional configuration changes can be made and packages installed just like any other Ubuntu system.
1.4 Managing a Container
Once launched, a container will continue to run until it is stopped via podman, or the command that was launched when the container was run exits. Running the following command on the host, for example, will cause the container to exit:
$ podman stop mycontainer
Alternatively, pressing the Ctrl-D keyboard sequence within the last remaining bash shell of the container would cause both the shell and container to exit. Once it has exited, the status of the container will change accordingly:
$ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4b49ddeb2987 docker.io/library/ubuntu:latest /bin/bash 6 minutes ago Exited (127) About a minute ago mycontainer
Although the container is no longer running, it still exists and contains all of the changes that were made to the configuration and file system. If you installed packages, made configuration changes or added files, these changes will persist within “mycontainer”. To verify this, simply restart the container as follows:
$ podman start mycontainer
After starting the container, use the podman exec command once again to execute commands within the container as outlined previously. For example, to once again gain access to a shell prompt:
![]() |
You are reading a sample chapter from Ubuntu 20.04 Essentials. Buy the full book now in eBook ($14.99) or Print ($36.99) format. Includes 37 chapters. Learn more. |
$ podman exec -it mycontainer /bin/bash
A running container may also be paused and resumed using the podman pause and unpause commands as follows:
$ podman pause mycontainer $ podman unpause mycontainer
1.5 Saving a Container to an Image
Once the container guest system is configured to your requirements there is a good chance that you will want to create and run more than one container of this particular type. To do this, the container needs to be saved as an image to local storage so that it can be used as the basis for additional container instances. This is achieved using the podman commit command combined with the name or ID of the container and the name by which the image will be stored, for example:
$ podman commit mycontainer > myubuntu_image
Once the image has been saved, check that it now appears in the list of images in the local repository:
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/myubuntu_image latest 8ad685d49482 47 seconds ago 66.6 MB docker.io/library/ubuntu latest 4e5021d210f6 3 weeks ago 66.6 MB
The saved image can now be used to create additional containers identical to the original:
$ podman run --name=mycontainer2 -it localhost/myubuntu_image /bin/bash
1.6 Removing an Image from Local Storage
To remove an image from local storage once it is no longer needed, simply run the podman rmi command, referencing either the image name or ID as output by the podman images command. For example, to remove the image named myubuntu_image created in the previous section, run podman as follows:
![]() |
You are reading a sample chapter from Ubuntu 20.04 Essentials. Buy the full book now in eBook ($14.99) or Print ($36.99) format. Includes 37 chapters. Learn more. |
$ podman rmi localhost/myubuntu_image
Note before an image can be removed, any containers based on that image must first be removed.
1.7 Removing Containers
Even when a container has exited or been stopped, it still exists and can be restarted at any time. If a container is no longer needed, it can be deleted using the podman rm command as follows after the container has been stopped:
# podman rm mycontainer2
1.8 Building a Container with Buildah
Buildah allows new containers to be built either from existing containers, an image or entirely from scratch. Buildah also includes the ability to mount the file system of a container so that it can be accessed and modified from the host.
The following buildah command, for example, will build a container from the Ubuntu Base image (if the image has not already been pulled from the registry, buildah will download it before creating the container):
$ buildah from docker://docker.io/library/ubuntu:latest
The result of running this command will be a container named ubuntu-working-container that is ready to run:
![]() |
You are reading a sample chapter from Ubuntu 20.04 Essentials. Buy the full book now in eBook ($14.99) or Print ($36.99) format. Includes 37 chapters. Learn more. |
$ buildah run ubuntu-working-container cat /etc/passwd
1.9 Summary
This chapter has worked through the creation and management of Linux Containers on Ubuntu using the podman, skopeo and buildah tools.