Expert · Boot, recovery and containers · topic 42 of 57 · 35 min
Containers with Podman: images, run, ports and logs
Explanation
Containers and virtual machines
A virtual machine simulates a whole computer, with its own kernel. A container is just a group of normal processes on the host, but the kernel gives them their own view of files, network, process list and users (namespaces) and limits their resources (cgroups). Containers start in a second and use far less memory, which is why apps are now often shipped as container images.
Images, containers and registries
- Image: a read-only package with an application and its files, built in layers. Like a template.
- Container: a running (or stopped) instance of an image, with a thin writable layer on top.
- Registry: a server that stores images, such as registry.access.redhat.com (Red Hat's public images), registry.redhat.io (needs a Red Hat login) or quay.io.
- Image name: registry/namespace/name:tag, for example registry.access.redhat.com/ubi9/httpd-24:latest. The tag picks a version; if you leave it out, latest is used.
UBI (Universal Base Image) images are RHEL-based images that Red Hat lets anyone use and redistribute, a good base for your own containers.
First container
$ sudo dnf install -y container-tools # podman, skopeo, buildah
$ podman search httpd-24 --limit 3
$ podman pull registry.access.redhat.com/ubi9/httpd-24
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.access.redhat.com/ubi9/httpd-24 latest 2b6f1c7e8d9a 2 weeks ago 387 MB
$ podman run -d --name web -p 8080:8080 registry.access.redhat.com/ubi9/httpd-24
5c1e9f0a7b...
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c1e9f0a7b2d registry.access.redhat.com/ubi9/httpd-24:latest /usr/bin/run-http... 5 seconds ago Up 5 seconds 0.0.0.0:8080->8080/tcp web
$ curl -s localhost:8080 | head -1
<!DOCTYPE html>Everyday commands
$ podman logs web # the container's output (add -f to follow)
$ podman exec -it web /bin/bash # a shell inside the running container
$ podman inspect web | grep -i ipaddress
$ podman stop web; podman start web
$ podman rm web # remove a stopped container (-f to force a running one)
$ podman rmi registry.access.redhat.com/ubi9/httpd-24 # remove the image
$ podman run --rm -it registry.access.redhat.com/ubi9/ubi cat /etc/redhat-release
Red Hat Enterprise Linux release 9.4 (Plow)Many images are configured with environment variables, passed with -e. For example a MariaDB image needs a root password and a database name: podman run -d --name db -e MYSQL_ROOT_PASSWORD=... -e MYSQL_DATABASE=shop -p 3306:3306 registry.redhat.io/rhel9/mariadb-105. The image's documentation lists its variables.
Rootless by default
When a normal user runs podman, the containers are rootless: they run with that user's rights on the host, even if the program inside thinks it is root. A break-out from the container gets only that user's access. Each user has their own images and containers (stored in ~/.local/share/containers). Rootless containers cannot publish host ports below 1024 by default, which is why the example uses 8080, not 80.
Common mistakes
- Using -p 8080 alone, or swapping the order. The format is -p HOST_PORT:CONTAINER_PORT.
- Expecting data written inside a container to survive podman rm. The container's own layer is deleted with it; use volumes (next lesson).
- Running podman with sudo and then looking for the container as a normal user, or the reverse: root and each user see different containers.
- Forgetting the host firewall when others must reach the published port.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Containers with Podman: images, run, ports and logs · 1/6
A container is a group of processes with its own view of files and network, sharing the host kernel.
Prefer a video by a teacher? Find free videos on “podman tutorial rhel 9 run container ports beginners” on YouTube ↗
In real life: Same app, every environment, at a Pune SaaS company
A Pune SaaS team used to fight "works on my machine" bugs between developer laptops, test and production. They now build one container image per release and push it to their registry. The test server and the production RHEL servers run exactly the same image with podman, only with different environment variables. Rolling back a bad release means running the previous image tag.
$ podman run -d --name api -p 8443:8443 -e APP_ENV=production registry.example.com/billing/api:2.7.1
$ podman ps --format "{{.Names}} {{.Image}} {{.Status}}"
api registry.example.com/billing/api:2.7.1 Up 3 hoursPractice (0/3 done)
In "podman run -d -p 8080:80 nginx", which is the port on the HOST?
Write parse_image(ref) that splits a container image reference into a dict with registry, path and tag. Rules: the tag is after the last ":" only if that colon comes after the last "/"; otherwise the tag is "latest". The registry is the first part before "/" if it contains a "." or ":" or is "localhost"; otherwise the registry is "" (unqualified). path is the rest. Example: "registry.access.redhat.com/ubi9/httpd-24:1-300" → {"registry": "registry.access.redhat.com", "path": "ubi9/httpd-24", "tag": "1-300"}.
As a normal user, run the UBI httpd image published on port 8080, change its home page from inside the container, check the logs, then stop and remove it.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Persistent storage and containers as systemd servicesBoot, recovery and containers · same module
- GRUB2, kernel arguments and the default kernelBoot, recovery and containers · same module
- Containers, images and registriesDevOps: Git, Docker, Kubernetes and CI/CD · Docker
- Containers, images and registriesCloud Computing (AWS, Azure, Google Cloud) · Containers in the cloud
- Running containers: ports, volumes, networks and limitsDevOps: Git, Docker, Kubernetes and CI/CD · Docker
- Docker: packaging your appBackend Development · Deployment and scaling
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What do containers share with the host that virtual machines do not?
Answer: The kernel
Containers run on the host kernel.
Which command shows running containers?
Answer: podman ps
podman ps (add -a for stopped ones too).
Which tag is used if you do not give one?
Answer: latest
latest is the default tag.
Why can't a rootless container publish host port 80 by default?
Answer: Ports below 1024 need root privileges
Unprivileged users cannot bind low ports by default.
What does podman exec -it web /bin/bash do?
Answer: Opens a shell inside the running container web
exec runs a command in a running container.
Why does a container start much faster than a virtual machine?Related
Answer: It does not boot an operating system kernel; it is just an isolated process
The host kernel is already running, so starting a container is close to starting a process.
What is Google Cloud's current registry for container images?Related
Answer: Artifact Registry
Artifact Registry replaced Container Registry.
What happens to files written inside a container (not in a volume) after podman rm?Related
Answer: They are deleted with the container
The container layer is removed.
Two containers are on the default bridge network. Why can the api container not reach the database at the host name db?Related
Answer: The default bridge network has no DNS by container name; use a user-defined network
User-defined bridge networks provide name resolution; the default bridge does not.
From Running containers: ports, volumes, networks and limits
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Boot, recovery and containers” before its exam: Persistent storage and containers as systemd services.
- Module 8 exam: Boot, recovery and containers · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Ansible fundamentals. 57 topics left in the course before the final exam.