Skip to content

eriksjolund/using-podman-quick-instructions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 

Repository files navigation

Using podman quick instructions

These instructions assume that

  • you have some knowledge about basic Linux commands such as ls, cat, echo and grep
  • you have a Linux computer with podman installed. (Installation instructions)

Table of contents

Basic usage

Show the podman version

[me@linux ~]$ podman --version
podman version 1.8.0
[me@linux ~]$ 

Run the command echo Hello! in the container docker.io/library/ubuntu:18.04

[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 echo Hello!
Trying to pull docker.io/library/ubuntu:18.04...
Getting image source signatures
Copying blob de83a2304fa1 done  
Copying blob b6b53be908de done  
Copying blob 423ae2b273f4 done  
Copying blob f9a83bce3af0 done  
Copying config 72300a873c done  
Writing manifest to image destination
Storing signatures
Hello!
[me@linux ~]$ 

The first lines of the text were printed to stderr telling us that podman needed to download the container image.

The last line of the text was printed to stdout and originates from the command echo Hello! that was run inside the container.

If we run the same command again

[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 echo Hello!
Hello!
[me@linux ~]$ 

we see that the download step could be skipped.

The size of the downloaded container image docker.io/library/ubuntu:18.04 is 66.6 MB

[me@linux ~]$ podman images
REPOSITORY                  TAG           IMAGE ID       CREATED        SIZE
docker.io/library/ubuntu    18.04         72300a873c2c   4 days ago     66.6 MB
[me@linux ~]$ 

but container images can be much smaller than that. For instance the popular container image docker.io/library/alpine:latest is about 6 MB.

The difference between the host system and the container

If we run the command cat /etc/os-release inside the container

[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
[me@linux ~]$ 

we see the contents of the file /etc/os-release inside the container image.

If we run cat /etc/os-release without podman

[me@linux ~]$ cat /etc/os-release
NAME=Fedora
VERSION="31 (Thirty One)"
ID=fedora
VERSION_ID=31
VERSION_CODENAME=""
PLATFORM_ID="platform:f31"
PRETTY_NAME="Fedora 31 (Thirty One)"
ANSI_COLOR="0;34"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:31"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f31/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=31
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=31
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
[me@linux ~]$ 

we see the contents of the file /etc/os-release on the host system.

Files on the host system are not accessible from within the container by default

The home directory

[me@linux ~]$ ls -d /home/me
/home/me
[me@linux ~]$ 

on the host system is not available from inside the container

[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 ls -d /home/me
ls: cannot access '/home/me': No such file or directory
[me@linux ~]$ 

This is because the host system and the container have different file trees.

How to let the container read and write to a directory on the host system

To run a command in the container with read and write access to the directory /home/me/project1 on the host system, add the command line option -v /home/me/project1:/some/path:Z.

[me@linux ~]$ echo abc > /home/me/project1/file1.txt
[me@linux ~]$ ls /home/me/project1
file1.txt
[me@linux ~]$ cat /home/me/project1
abc
[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 -v /home/me/project1:/some/path:Z cat /some/path/file1.txt
abc
[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 -v /home/me/project1:/some/path:Z rm /some/path/file1.txt
[me@linux ~]$ ls /home/me/project1
[me@linux ~]$ 

The path inside the container /some/path was chosen arbitrarily. To simplify things, you would often want to use the same path both outside and inside the container, i.e using the command line option -v /home/me/project1:/home/me/project1:Z.

Popular Linux container images

Container image Size (MB) Comment
registry.fedoraproject.org/fedora:31 200 Fedora 31
docker.io/library/fedora:31 200 docker.io also provides Fedora 31
docker.io/library/centos:8 245 CentOS 8
docker.io/library/ubuntu:19.10 75 Ubuntu 19.10
docker.io/library/ubuntu:18.04 67 Ubuntu 18.04 LTS (Long Term Support)
docker.io/library/alpine:3 6 If you want to create very small container images. ⚠️ Requires a bit more expertise to work with.

Install a missing software package

Goal of the exercise:

Resize the photo ~/img/photo.jpg

to half the size

and save it to ~/img/resized_photo.jpg by using gm convert -resize 50% (from the software package GraphicsMagick).

Is the software package already installed?

Is GraphicsMagick already installed?

Example Ubuntu LTS : Is GraphicsMagick already installed?

Check the container image docker.io/library/ubuntu:18.04

[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 dpkg -l | grep -i graphicsmagick
[me@linux ~]$ 

Example Fedora : Is GraphicsMagick already installed?

Check the container image registry.fedoraproject.org/fedora:31

[me@linux ~]$ podman run --rm registry.fedoraproject.org/fedora:31 rpm -qa | grep -i graphicsmagick
[me@linux ~]$ 

Example CentOS : Is GraphicsMagick already installed?

Check the container image docker.io/library/centos:8

[me@linux ~]$ podman run --rm docker.io/library/centos:8 rpm -qa | grep -i graphicsmagick
[me@linux ~]$ 

Example Alpine : Is GraphicsMagick already installed?

Check the container image docker.io/library/alpine:3

[me@linux ~]$ podman run --rm docker.io/library/alpine:3 apk --no-cache list -a | grep -i graphicsmagick
[me@linux ~]$ 

Results of the tests: Is GraphicsMagick already installed?

Container image GraphicsMagick already installed? (Yes/No)
docker.io/library/ubuntu:18.04 No
registry.fedoraproject.org/fedora:31 No
docker.io/library/centos:8 No
docker.io/library/alpine:3 No

Is the software package available in a package repository?

Is GraphicsMagick available in a package repository?

Example Fedora : Is GraphicsMagick available in a package repository?

Check the container image registry.fedoraproject.org/fedora:31

[me@linux ~]$ podman run --rm registry.fedoraproject.org/fedora:31 dnf list available | grep -i graphicsmagick
GraphicsMagick.i686                                                        1.3.34-1.fc31                                                    updates        
GraphicsMagick.x86_64                                                      1.3.34-1.fc31                                                    updates        
GraphicsMagick-c++.i686                                                    1.3.34-1.fc31                                                    updates        
GraphicsMagick-c++.x86_64                                                  1.3.34-1.fc31                                                    updates        
GraphicsMagick-c++-devel.i686                                              1.3.34-1.fc31                                                    updates        
GraphicsMagick-c++-devel.x86_64                                            1.3.34-1.fc31                                                    updates        
GraphicsMagick-devel.i686                                                  1.3.34-1.fc31                                                    updates        
GraphicsMagick-devel.x86_64                                                1.3.34-1.fc31                                                    updates        
GraphicsMagick-doc.noarch                                                  1.3.34-1.fc31                                                    updates        
GraphicsMagick-perl.x86_64                                                 1.3.34-1.fc31                                                    updates    
[me@linux ~]$ 

(The website https://apps.fedoraproject.org/packages/ provides the same information)

Example CentOS : Is GraphicsMagick available in a package repository?

Check the container image docker.io/library/centos:8

[me@linux ~]$ podman run --rm docker.io/library/centos:8 dnf list available | grep -i graphicsmagick
[me@linux ~]$ 

Nothing there.

Let's check the extra repository PowerTools

[me@linux ~]$ podman run --rm docker.io/library/centos:8 dnf repository-packages PowerTools list | grep -i graphicsmagick
[me@linux ~]$ 

Nothing there.

Let's check the third-party repository EPEL.

[me@linux ~]$ podman run --rm docker.io/library/centos:8 /bin/bash -c "dnf -y update && dnf -y install epel-release && dnf repository-packages epel list" | grep -i graphicsmagick
warning: /var/cache/dnf/AppStream-02e86d1c976ab532/packages/libxkbcommon-0.8.2-1.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
Importing GPG key 0x8483C65D:
 Userid     : "CentOS (CentOS Official Signing Key) <[email protected]>"
 Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
GraphicsMagick.x86_64                              1.3.34-1.el8                           epel
GraphicsMagick-c++.x86_64                          1.3.34-1.el8                           epel
GraphicsMagick-c++-devel.x86_64                    1.3.34-1.el8                           epel
GraphicsMagick-devel.x86_64                        1.3.34-1.el8                           epel
GraphicsMagick-doc.noarch                          1.3.34-1.el8                           epel
GraphicsMagick-perl.x86_64                         1.3.34-1.el8                           epel
[me@linux ~]$ 

Example Ubuntu LTS : Is GraphicsMagick available in a package repository?

Check the container image docker.io/library/ubuntu:18.04

[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 /bin/bash -c "apt-get update && apt-cache search GraphicsMagick" | grep -i ^graphicsmagick
graphicsmagick - collection of image processing tools
graphicsmagick-dbg - format-independent image processing - debugging symbols
graphicsmagick-imagemagick-compat - image processing tools providing ImageMagick interface
graphicsmagick-libmagick-dev-compat - image processing libraries providing ImageMagick interface
[me@linux ~]$ 

(The website https://packages.ubuntu.com/ provides the same information)

Example Alpine : Is GraphicsMagick available in a package repository?

Check the container image docker.io/library/alpine:3

[me@linux ~]$ podman run --rm docker.io/library/alpine:3 apk --no-cache list -a | grep -i graphicsmagick
graphicsmagick-zsh-completion-5.7.1-r0 x86_64 {zsh} (custom)
graphicsmagick-1.3.33-r1 x86_64 {graphicsmagick} (MIT)
graphicsmagick-dev-1.3.33-r1 x86_64 {graphicsmagick} (MIT)
graphicsmagick-doc-1.3.33-r1 x86_64 {graphicsmagick} (MIT)
[me@linux ~]$ 

(The website https://pkgs.alpinelinux.org/packages provides the same information)

Results of the tests: Is GraphicsMagick available in a package repository?

GraphicsMagick is available in package repositories!

Container image Command to install GraphicsMagick
docker.io/library/ubuntu:18.04 apt-get update && apt-get install -y graphicsmagick
registry.fedoraproject.org/fedora:31 dnf -y update && dnf -y install GraphicsMagick
docker.io/library/centos:8 dnf -y update && dnf -y install epel-release && dnf -y install GraphicsMagick
docker.io/library/alpine:3 apk --no-cache add graphicsmagick

But you will need to use podman build to save the result to a new container image.

Use podman build to run an install command and then save the result to a new container image

Example Fedora : Install GraphicsMagick with podman build

To install GraphicsMagick on docker.io/library/fedora:31 and save the result to the new container image localhost/foobar:fedora31, copy-paste these lines into the terminal

echo "FROM docker.io/library/fedora:31
RUN dnf -y update && dnf -y install GraphicsMagick && dnf clean all
" | podman build -t foobar:fedora31 -

Show details about the new container

[me@linux ~]$ podman images --filter reference=localhost/foobar:fedora31
REPOSITORY         TAG           IMAGE ID       CREATED          SIZE
localhost/foobar   fedora31   3ea792460e93   20 seconds ago   259 MB
[me@linux ~]$ 

The && dnf clean all was added to reduce the size of the container image, otherwise the size would have been 478 MB.

The text strings foobar and fedora31 in localhost/foobar:fedora31 were arbitrarily chosen. The syntax is localhost/name:tag.

Example CentOS : Install GraphicsMagick with podman build

To install GraphicsMagick on docker.io/library/centos:8 and save the result to the new container image localhost/foobar:centos8, copy-paste these lines into the terminal

echo "FROM docker.io/library/centos:8
RUN dnf -y update && dnf -y install epel-release && dnf -y install GraphicsMagick && dnf clean all
" | podman build -t foobar:centos8 -

Show details about the new container

[me@linux ~]$ podman images --filter reference=localhost/foobar:centos8
REPOSITORY         TAG           IMAGE ID       CREATED          SIZE
localhost/foobar   centos8   ddbad21e0684   36 seconds ago   395 MB
[me@linux ~]$ 

The && dnf clean all was added to reduce the size of the container image, otherwise the size would have been 433 MB.

The text strings foobar and centos8 in localhost/foobar:centos8 were arbitrarily chosen. The syntax is localhost/name:tag.

Example Ubuntu LTS : Install GraphicsMagick with podman build

To install GraphicsMagick on docker.io/library/ubuntu:18.04 and save the result to the new container image localhost/foobar:ubuntu1804, copy-paste these lines into the terminal

echo "FROM docker.io/library/ubuntu:18.04
RUN apt-get update && apt-get install -y --no-install-recommends graphicsmagick && rm -rf /var/lib/apt/lists/*
" | podman build -t foobar:ubuntu1804 -

Show details about the new container

[me@linux ~]$ podman images --filter reference=localhost/foobar:ubuntu1804
REPOSITORY         TAG           IMAGE ID       CREATED          SIZE
localhost/foobar   ubuntu1804   891d0886ab51  15 seconds ago   112 MB
[me@linux ~]$ 

Both --no-install-recommends and && rm -rf /var/lib/apt/lists/* were added to reduce the size of the container image.

Image size Installation command
198 MB apt-get update && apt-get install -y graphicsmagick
170 MB apt-get update && apt-get install -y graphicsmagick && rm -rf /var/lib/apt/lists/*
112 MB apt-get update && apt-get install -y --no-install-recommends graphicsmagick && rm -rf /var/lib/apt/lists/*

The text strings foobar and ubuntu1804 in localhost/foobar:ubuntu1804 were arbitrarily chosen. The syntax is localhost/name:tag.

Example Alpine : Install GraphicsMagick with podman build

To install GraphicsMagick on docker.io/library/alpine:3 and save the result to the new container image localhost/foobar:alpine3, copy-paste these lines into the terminal

echo "FROM docker.io/library/alpine:3
RUN apk --no-cache add graphicsmagick
" | podman build -t foobar:alpine3 -

Show details about the new container

[me@linux ~]$ podman images --filter reference=localhost/foobar:alpine3
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
localhost/foobar   alpine3   93a5ac124e03   35 seconds ago   24.8 MB
[me@linux ~]$ 

The text strings foobar and alpine3 in localhost/foobar:alpine3 were arbitrarily chosen. The syntax is localhost/name:tag.

Compare the sizes of the built images

The container images ordered in size

Container image Installation command
localhost/foobar:alpine3 24.8 MB
localhost/foobar:ubuntu1804 112 MB
localhost/foobar:fedora31 259 MB
localhost/foobar:centos8 395 MB

Use the installed software package (resize a photo with GraphicsMagick)

Although the containers have been built with different commands and from different Linux distributions, the resulting container images will behave quite similarly when they are used.

The following examples show how similar they are from a user perspective.

Example Fedora : Resize a photo with GraphicsMagick

Let's use the previously built container image localhost/foobar:fedora31

[me@linux ~]$ podman images --filter reference=localhost/foobar:fedora31
REPOSITORY         TAG           IMAGE ID       CREATED          SIZE
localhost/foobar   fedora31   3ea792460e93   1 hour ago   259 MB
[me@linux ~]$ 

to resize the photo /home/me/img/photo.jpg

[me@linux ~]$ ls /home/me/img/
photo.jpg
[me@linux ~]$ podman run --rm -v /home/me/img:/home/me/img:Z localhost/foobar:fedora31 gm convert -resize 50% /home/me/img/photo.jpg /home/me/img/resized_photo.jpg
[me@linux ~]$ ls /home/me/img/
photo.jpg
photo_resized.jpg
[me@linux ~]$ 

Show the GraphicsMagick version

[me@linux ~]$ podman run --rm localhost/foobar:fedora31 gm version | head -1
GraphicsMagick 1.3.34 2019-12-24 Q16 http://www.GraphicsMagick.org/

Example CentOS : Resize a photo with GraphicsMagick

Let's use the previously built container image localhost/foobar:centos8

[me@linux ~]$ podman images --filter reference=localhost/foobar:centos8
REPOSITORY         TAG           IMAGE ID       CREATED          SIZE
localhost/foobar   centos8   ddbad21e0684   1 hour ago   395 MB
[me@linux ~]$ 

to resize the photo /home/me/img/photo.jpg

[me@linux ~]$ ls /home/me/img/
photo.jpg
[me@linux ~]$ podman run --rm -v /home/me/img:/home/me/img:Z localhost/foobar:centos8 gm convert -resize 50% /home/me/img/photo.jpg /home/me/img/resized_photo.jpg
[me@linux ~]$ ls /home/me/img/
photo.jpg
photo_resized.jpg
[me@linux ~]$ 

Show the GraphicsMagick version

[me@linux ~]$ podman run --rm localhost/foobar:centos8 gm version | head -1
GraphicsMagick 1.3.34 2019-12-24 Q16 http://www.GraphicsMagick.org/

Example Ubuntu LTS : Resize a photo with GraphicsMagick

Let's use the previously built container image localhost/foobar:ubuntu1804

[me@linux ~]$ podman images --filter reference=localhost/foobar:ubuntu1804
REPOSITORY         TAG           IMAGE ID       CREATED          SIZE
localhost/foobar   ubuntu1804   891d0886ab51  1 hour ago   112 MB
[me@linux ~]$ 

to resize the photo /home/me/img/photo.jpg

[me@linux ~]$ ls /home/me/img/
photo.jpg
[me@linux ~]$ podman run --rm -v /home/me/img:/home/me/img:Z localhost/foobar:ubuntu1804 gm convert -resize 50% /home/me/img/photo.jpg /home/me/img/resized_photo.jpg
[me@linux ~]$ ls /home/me/img/
photo.jpg
photo_resized.jpg
[me@linux ~]$ 

Show the GraphicsMagick version

[me@linux ~]$ podman run --rm localhost/foobar:ubuntu1804 gm version | head -1
GraphicsMagick 1.3.28 2018-01-20 Q16 http://www.GraphicsMagick.org/

Example Alpine : Resize a photo with GraphicsMagick

Let's use the previously built container image localhost/foobar:alpine3

[me@linux ~]$ podman images --filter reference=localhost/foobar:alpine3
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
localhost/foobar   alpine3   93a5ac124e03   2 hours ago   24.8 MB
[me@linux ~]$ 

to resize the photo /home/me/img/photo.jpg

[me@linux ~]$ ls /home/me/img/
photo.jpg
[me@linux ~]$ podman run --rm -v /home/me/img:/home/me/img:Z localhost/foobar:alpine3 gm convert -resize 50% /home/me/img/photo.jpg /home/me/img/resized_photo.jpg
[me@linux ~]$ ls /home/me/img/
photo.jpg
photo_resized.jpg
[me@linux ~]$ 

Show the GraphicsMagick version

[me@linux ~]$ podman run --rm localhost/foobar:alpine3 gm version | head -1
GraphicsMagick 1.3.33 2019-07-20 Q16 http://www.GraphicsMagick.org/

Search for a pre-built container image

Instead of building your own container image you can often find a pre-built container image in one of the popular container image registries.

Example: Search docker.io

Let's search for a pre-built container image that has the software GraphicsMagick installed.

A search for GraphicsMagic on https://hub.docker.com/ results in a list of about 100 different container images from the registry docker.io. The results are ordered in popularity. One of the most popular at the time of writing is https://hub.docker.com/r/jameskyburz/graphicsmagick-alpine/tags

It has a few different versions. To the right-hand side of the web page, you see for instance the text

docker pull jameskyburz/graphicsmagick-alpine:v3.0.0

That is the docker command to download ("pull") that version of the container image.

podman is aiming to be a drop-in replacement for the docker command. When working with podman it is better to use the full path of the container image, i.e. always prepend "docker.io/" to the container image names found at https://hub.docker.com/.

In other words, use

docker.io/jameskyburz/graphicsmagick-alpine:v3.0.0

instead of

jameskyburz/graphicsmagick-alpine:v3.0.0.

The corresponding podman command is therefore

podman pull docker.io/jameskyburz/graphicsmagick-alpine:v3.0.0

To resize the photo /home/me/img/photo.jpg

[me@linux ~]$ ls /home/me/img/
photo.jpg
[me@linux ~]$ podman run --rm -v /home/me/img:/home/me/img:Z docker.io/jameskyburz/graphicsmagick-alpine:v3.0.0 gm convert -resize 50% /home/me/img/photo.jpg /home/me/img/resized_photo.jpg
[me@linux ~]$ ls /home/me/img/
photo.jpg
photo_resized.jpg
[me@linux ~]$ 

Security

Consider the risc of malicious code in pre-built container images

Container images under docker.io/library/* are official Docker library images. Normally we should be able to trust those more than a container image published by an arbitrary user at docker.io/username/containername:tag.

Luckily using podman run for executables of unknown origin in containers is safer

[me@linux ~]$ podman run --rm example.com/hacker/malicious:v1 malicious_executable

than executing an untrusted executable directly

[me@linux ~]$ wget http://example.com/malicious_executable
[me@linux ~]$ chmod 755 malicious_executable
[me@linux ~]$ ./malicious_executable

The reason is that podman run provides extra encapsulation protection.

  • Write access to directories on the host system need to be granted explicitly with (--volume, -v).
  • add more items here ...

How to run a command in a container image in a more secure and restricted way

A command for resizing photos should not need access to the network. To disable network access, add --net none as an argument to podman run.

podman run can be restricted even further by for instance

  • --read-only=true
  • --security-opt=
  • --ulimit=option
  • --cap-drop=
  • --cpu-quota=
  • --shm-size=
  • --http-proxy=false
  • --volume (-v) can be made read-only
  • --security-opt=seccomp=profile.json
  • --security-opt=no-new-privileges

Man page for podman run: https://github.com/containers/libpod/blob/master/docs/source/markdown/podman-run.1.md

How to save disk space

Easy tip: Use containers based on Alpine

Alpine container images are very small.

Easy tip: Remove unnecessary container images

podman rmi imagename

Example: Removing container image localhost/foobar:centos8

[me@linux ~]$ podman images --filter reference=localhost/foobar:centos8
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
localhost/foobar   centos8   b1d1374ebbbf   31 minutes ago   395 MB
[me@linux ~]$ df -h --output=avail .
Avail
 9.0G
[me@linux ~]$ podman rmi localhost/foobar:centos8
Untagged: localhost/foobar:centos8
Deleted: b1d1374ebbbf650b34b81f0a3a3cb8cfba0a5b98da57582c70373d6abe695459
[me@linux ~]$ df -h --output=avail .
Avail
 9.2G
[me@linux ~]$ 

The command podman images --sort size lists the images in size order.

To list the biggest container image

[me@linux ~]$ podman images --sort size | tail -1
<none>                              <none>       a4977efc66f2   8 days ago     1.56 GB
[me@linux ~]$ 

How to save time

Speed up podman build by reusing the package metadata cache

The first step of a container build is often to download metadata from the package repositories and post-process the data.

This build step may take half a minute or so but luckily we can avoid it by reusing the result.

The trick is to create the package metadata cache in advance and reuse it with an overlay mount.

Example Fedora : Speed up podman build by reusing the DNF metadata cache

Let's assume we are building containers based on Fedora 31.

First, create an empty directory, for instance /home/me/f31cache.

[me@linux ~]$ mkdir $HOME/f31cache
[me@linux ~]$ 

Fill the directory with the most recent dnf metadata cache for Fedora 31.

[me@linux ~]$ time podman run --rm -v $HOME/f31cache:/var/cache/dnf:Z registry.fedoraproject.org/fedora:31 dnf makecache
Fedora Modular 31 - x86_64                      413 kB/s | 5.2 MB     00:12    
Fedora Modular 31 - x86_64 - Updates            3.0 MB/s | 4.0 MB     00:01    
Fedora 31 - x86_64 - Updates                     16 MB/s |  22 MB     00:01    
Fedora 31 - x86_64                               30 MB/s |  71 MB     00:02    
Last metadata expiration check: 0:00:01 ago on Sat Mar 21 18:50:20 2020.
Metadata cache created.

real	0m36.327s
user	0m0.152s
sys	0m0.076s
[me@linux ~]$ 

The command took 36 seconds to finish.

[me@linux ~]$ du -sh $HOME/f31cache
212M	/home/me/f31cache

The directory consumes 212 MB of disk space.

Let's rebuild the previously built container image localhost/foobar:fedora31, but now by reusing the DNF metadata cache from /home/me/f31cache.

Copy-paste these lines into the terminal

echo "FROM docker.io/library/fedora:31
RUN dnf -y update && dnf -y install epel-release && dnf -y install GraphicsMagick && dnf clean all
" | time podman build -v $HOME/f31cache:/var/cache/dnf:O -t foobar:fedora31 -

The podman build command finishes succesfully. time prints

0.17user 0.06system 0:00.22elapsed 104%CPU (0avgtext+0avgdata 42212maxresident)k
0inputs+3232outputs (0major+6383minor)pagefaults 0swaps

0.22 seconds! Less than one second! No, that is too fast to believe it's true. We need to add the flag --no-cache so that podman will actually rebuild the container image without reusing cached results.

A second trial:

Copy-paste these lines into the terminal

echo "FROM docker.io/library/fedora:31
RUN dnf -y update && dnf -y install epel-release && dnf -y install GraphicsMagick && dnf clean all
" | time podman build --no-cache -v $HOME/f31cache:/var/cache/dnf:O -t foobar:fedora31 -

The podman build command finishes succesfully. time prints

13.73user 3.20system 0:25.77elapsed 65%CPU (0avgtext+0avgdata 173404maxresident)k
553208inputs+523056outputs (453major+320854minor)pagefaults 0swaps

About 26 seconds!

A normal build without -v $HOME/f31y3:/var/cache/dnf:O takes 52 seconds.

Conclusion: Reusing the DNF metadata cache speeds things up.

The blog post Speeding up container image builds with Buildah provides more details.

Linux container images for the brave adventurous user not afraid of bugs

Container image Size (MB) Comment
registry.fedoraproject.org/fedora:rawhide 207 The latest development of Fedora (not yet released). ⚠️ Expect more bugs.
docker.io/library/alpine:edge 6 The latest development of Alpine (not yet released). ⚠️ Expect more bugs.
docker.io/library/debian:unstable 123 The latest development of Debian (not yet released). ⚠️ Expect more bugs.

When to use the flags -i (--interactive) and -t (--tty)

If your program reads from stdin, use the command line flag -i

[me@linux ~]$ echo Just one line | podman run --rm -i docker.io/library/ubuntu:18.04 wc -l
1
[me@linux ~]$ 

If your program needs interaction over the terminal, use the command line flags -t and -i

[me@linux ~]$ podman run --rm -ti docker.io/library/ubuntu:18.04 /bin/bash -c 'echo -n "Type something: "; read aa; echo "You typed: $aa"'
Type something: abc
You typed: abc
[me@linux ~]$ 

⚠️ Using the -t flag may slightly modify the output, by adding extra carriage return characters. This might be very surprising. The extra carrage return (\r) is not added by podman, but by the terminal.

[me@linux ~]$ echo abc | od -c
0000000   a   b   c  \n
0000004
[me@linux ~]$ podman run --rm docker.io/library/ubuntu:18.04 echo abc | od -c
0000000   a   b   c  \n
0000004
[me@linux ~]$ podman run --rm -ti docker.io/library/ubuntu:18.04 echo abc | od -c
0000000   a   b   c  \r  \n
0000005
[me@linux ~]$ 

The professional way, using Dockerfile and GitHub/GitLab

Using Github

Both GitHub and GitLab provide a hosted version control system. They are mainly used for hosting the source code of many software projects.

Create a public GitHub repo with a Dockerfile

First sign up for an (free) account on GitHub, if you haven't done so already. On the front page you will see a green button labeled "Sign up for GitHub".

Then create a new repo https://help.github.com/en/github/getting-started-with-github/create-a-repo

At step nr 4: Choose a repository visbility. choose Public.

At step nr 7: choose Commit directly to the master branch instead of Create a new branch for this commit and start a pull request.

In the web interface, create a new file named Dockerfile.

Yet to be written ...

About

Using podman quick instructions

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published