Chapter 21: Containers with Podman
Building your own image
You rarely run an image exactly as you find it. A Containerfile is a short recipe that starts from a base image and adds your files, so the result is the same on every machine. podman build turns it into a new local image.
- Write a short Containerfile with
FROM,COPYand, where needed,USERandCMD. - Build, tag, run and inspect the image.
- Explain layers, tags and digests, and what does not belong in an image.
The recipe
A Containerfile: Select an instruction.
The simplest useful image puts a web page inside the web server image. In a directory ~/portal create the page and the recipe:
[student@servera ~]$ mkdir -p ~/portal && cd ~/portal
[student@servera portal]$ echo "Portal is up" > index.html
[student@servera portal]$ cat > Containerfile <<'EOT'
FROM registry.access.redhat.com/ubi9/httpd-24:latest
COPY index.html /var/www/html/index.html
EOTBuild and run
From files to an image: Step through podman build.
[student@servera portal]$ podman build -t localhost/portal:1 .
STEP 1/2: FROM registry.access.redhat.com/ubi9/httpd-24:latest
STEP 2/2: COPY index.html /var/www/html/index.html
COMMIT localhost/portal:1
--> 49203ad043a3
Successfully tagged localhost/portal:1
49203ad043a3e208fce8ed4aeb3ff117a24e0cd63f212dd89e3aac708edab38c
[student@servera portal]$ podman run -d --name portal -p 8080:8080 localhost/portal:1
[student@servera portal]$ curl -s localhost:8080
Portal is up-t names and tags the image; the . is the build context, the directory whose files COPY may use. The page is part of the image now: there is no volume, and every container from this image shows the same page.
[student@servera portal]$ podman history localhost/portal:1 | head -3 | cut -c1-90
ID CREATED CREATED BY SIZE
cf1e25990315 Less than a second ago /bin/sh -c #(nop) COPY file:702c4212… in /var/www/html/index.html 2.56kBEach instruction is a layer; the small COPY layer sits on top of the large base image, so the new image costs almost no extra disk space.
Good habits
- Pin what you build on.
:latestcan change under you. Use a tested tag, or the digest:FROM registry.access.redhat.com/ubi9/httpd-24@sha256:…. - Build in the image what is fixed (program, page, configuration) and keep in a volume what changes (data, uploads, logs).
- No secrets in
COPY,ENVorRUN: they stay in the layers for good. - A container lives as long as its main process. A one-shot image (print a line and exit) is useful for commands, but it is not a service; under
Restart=alwaysit would restart forever. - Give versions to your own images (
:1,:2) so you can go back:podman tag localhost/portal:1 localhost/portal:latestadds a second name, andpodman rmiremoves a name. - The image exists only in your storage until you push it to a registry you control. Another machine cannot use
localhost/portal:1.
[student@servera portal]$ podman rm -f -t 1 portal
portal
[student@servera portal]$ podman images --format "{{.Repository}}:{{.Tag}} {{.Size}}"
localhost/portal:1 310 MB
registry.access.redhat.com/ubi9/httpd-24:latest 310 MBBoth lines show the same size because they share the base layers. (Stopping this web image waits ten seconds for a polite exit; -t 1 shortens that.)
Try it
Check your understanding
- Which instruction chooses the image you build upon?
- What is the difference between COPY and a volume?
- Why can a mutable tag such as latest be a problem?
- Where is localhost/portal:1 stored?
- Which command shows the layers of an image?
- A one-shot image that prints a line and exits is run under Restart=always in a service. What happens?