Essential Podman CLI Commands
The dozen commands that cover most days, and the `--format` template that turns any of them into a single line you can script against. Includes the environment variable that tells a process it is in a container.
Containers and Images Guide 6 of 47 Beginner
- OSUbuntu 26.04 LTS (resolute)
- Podman5.7.0
- Runtimecrun 1.21
- Networknetavark 1.16.1
- TimeAbout 14 min
- Reviewed22 August 2026
Written against the versions above. Podman follows the distribution here rather than a vendor repository, so the version you get is the one Ubuntu shipped. The commands are stable across 5.x.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| PODMAN01 | 192.168.0.21 | Ubuntu 26.04 LTS | Primary Container Host | 2 Core | 4 GB | 50 GB |
Before you start
- guide 10 - this guide works on the same container.
-
Run a command inside something already running
podman execruns a new process in an existing container's namespaces. Two shapes:podman exec site nginx -v- one command, output, donepodman exec -it site sh- an interactive shell, for looking around
Reading a config file out of a running container is the everyday use, and it answers a question that guessing cannot: not what the image is documented to contain, but what this container actually has.
Worth knowing that
execstarts a process outside the entrypoint's supervision. It is not part of the container's lifecycle, so it does not restart with it and killing it does not stop the container.bash Example session podman exec site nginx -vnginx version: nginx/1.31.4podman exec site cat /etc/nginx/conf.d/default.confserver { listen 80; listen [::]:80; server_name localhost; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; }Expected resultAn nginx version, then the default server block.
Success conditionYou have read a file out of a running container without stopping it.
-
Templates: --format is the whole scripting story
Almost every Podman command takes
--formatwith a Go template, and it is the difference between parsing output and asking for a value.Two forms worth memorising:
--format 'table {{.Names}} {{.Status}}'- pick columns, keep the header--format 'x={{.Field}}'- one line, no header, ready for a shell variable
Ranging over a list works too.
{{range .Config.Env}}{{println .}}{{end}}prints the container's environment, and the first line is the interesting one:container=podmanPodman sets that itself. A process inside can read
$containerto discover both that it is containerised and by what - which is how some software decides whether to expect systemd, or a real init, or a TTY.The field names come from the JSON that
podman inspectreturns with no--formatat all, so that is where to look when a template does not resolve.bash Example session podman inspect site --format 'image={{.ImageName}} started={{.State.StartedAt}} restarts={{.RestartCount}}'image=docker.io/library/nginx:alpine started=2026-08-22 11:35:41.711978243 +0000 UTC restarts=0podman inspect site --format '{{range .Config.Env}}{{println .}}{{end}}'container=podmanNJS_VERSION=1.0.0PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binNJS_RELEASE=1ACME_VERSION=0.4.1NGINX_VERSION=1.31.4PKG_RELEASE=1DYNPKG_RELEASE=1HOME=/rootHOSTNAME=725ae48d0232Expected resultOne summary line, then the container's environment with
container=podmanfirst.Success conditionYou can extract a single field without piping anything through
grep. -
Move a file out, and read the event log
podman cp site:/etc/nginx/nginx.conf ./nginx.confcopies out. It works in both directions and on stopped containers too, which makes it the usual way to retrieve something from a container that has already failed.podman eventsis the command most people discover last and then use constantly. It is one timeline of everything the engine did - creates, pulls, starts, deaths - and--since 3m --stream=falsegives a bounded chunk rather than a live tail.Look at what it remembers:
create objective_elgamal, the generated name of the throwaway container from the previous guide. The container is long gone and the event log still has it, which is exactly why this is the first place to look when something ran and vanished before you could inspect it.bash Example session podman cp site:/etc/nginx/nginx.conf ./nginx.confwc -l nginx.conf32 nginx.confpodman events --since 3m --stream=false --format '{{.Status}} {{.Name}}'refreshcreate objective_elgamalpull docker.io/library/alpineinit objective_elgamalstart objective_elgamalattach objective_elgamaldied objective_elgamalremove objective_elgamalExpected resultA 32-line file on the host, and an event list including the removed container's generated name.
Success conditionYou have a file from inside a container and a timeline of what the engine did.
Troubleshooting
podman execfails withcontainer state improper.Why:
execneeds a running container. A stopped one has no namespaces to enter.Fix:
podman startit first, or usepodman cpwhich works on stopped containers.A
--formattemplate prints nothing, or the literal template text.Why: A misspelled or wrongly-cased field. Templates are case sensitive and silently resolve unknown fields to empty.
Fix:Run the command with no
--formatto see the real JSON, and copy the field name from there.podman exec -itgivesthe input device is not a TTY.Why:
-twas requested in a context with no terminal - a script, a CI job, an ssh command with no TTY.Fix:Drop
-tand keep-i, or drop both for a non-interactive command.