Monitor Container Events with `podman events`

Tested on Red Hat Enterprise Linux 10.2 (Coughlan)
Package podman-5.8.2-5.el10_2.x86_64
Applies to Linux hosts with Podman where you need to watch or replay container, pod, image, and volume lifecycle actions
Privilege Normal user for rootless events; journald visibility may differ between root and rootless sessions
Scope podman events live streaming versus historical replay, --since and --until, --stream=false, --filter for container, event, type, pod, image, and label, --format Go templates and JSON, EventLogger backends (journald, file, none), healthcheck_events pointer, health_status events, overnight-death workflow with Podman logs and inspect, and logs versus events versus inspect. Does not cover application log tutorials, full journald administration, SIEM setup, or health-check probe configuration.
Related guides List containers with podman ps

podman events answers a different question than podman logs. Logs capture what the application printed. Events record what Podman did — create, start, stop, died, pull, remove, health transitions, and more.

By default the command streams and waits for new activity. Add --since with --stream=false when you need a bounded replay for scripts or incident review. That distinction matters before you open a terminal and wonder why nothing appears.


Check the active events backend first

Before relying on historical replay, confirm where Podman stores events on this host:

bash
podman info --format '{{.Host.EventLogger}}'

Sample output on RHEL 10.2:

output
journald

Supported values are journald, file, and none. The lab host uses journald with no override in /etc/containers/containers.conf. Your output may differ if an administrator set events_logger or events_logfile_path — see the backend sections later.


Watch Podman events live

Open a stream that prints each new lifecycle record as it happens:

bash
podman events

The command blocks until you press Ctrl+C. In a second terminal, run a short-lived container:

bash
podman run --rm docker.io/library/alpine:latest true

Sample lines from the live stream (IDs and attribute blobs trimmed):

output
2026-08-23 09:11:09.381706306 +0530 IST container create c928c73dee7d... (image=...)
2026-08-23 09:11:09.310561526 +0530 IST image pull d09203066f26... docker.io/library/alpine:latest
2026-08-23 09:11:10.030141604 +0530 IST container init c928c73dee7d... (image=...)
2026-08-23 09:11:10.073266423 +0530 IST container start c928c73dee7d... (image=...)
2026-08-23 09:11:10.088835045 +0530 IST container attach c928c73dee7d... (image=...)
2026-08-23 09:11:10.100445991 +0530 IST container died c928c73dee7d... (image=...)

A typical detached workload shows create, init, start, and later stop or died when it exits. Foreground podman run --rm adds attach before died. These lines are Podman lifecycle records, not application stdout.


Replay historical events with --since

List events from the last ten minutes and exit:

bash
podman events --since 10m --stream=false

--since accepts Go durations (5m, 1h, 1h30s) or RFC3339 timestamps. Without --since or --until, podman events stays in streaming mode and does not print past history.

Run a named container through a full stop/start/remove cycle, then replay:

bash
podman run -d --name evt-web docker.io/library/alpine:latest sleep 3600

Stop the container to generate stop and died lines:

bash
podman stop evt-web

Start it again so init and start events appear in the replay:

bash
podman start evt-web

Remove the container to finish the lifecycle:

bash
podman rm -f evt-web

Fetch the recent timeline:

bash
podman events --since 5m --stream=false

Sample output (trimmed):

output
2026-08-23 09:09:33.238287046 +0530 IST container create 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:33.5930725 +0530 IST container start 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:43.7968291 +0530 IST container died 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:44.521498231 +0530 IST container init 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:44.539162406 +0530 IST container start 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:54.676088774 +0530 IST container stop 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:54.703959447 +0530 IST container died 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:55.04714762 +0530 IST container remove 97e33d58e12f... (name=evt-web, ...)

On this host podman stop against sleep sometimes waits ten seconds then SIGKILLs; you may see died without a separate stop line on every path.


Narrow a time window with --until

Combine --since and --until to bracket an incident. This example asks for events older than ten minutes but newer than one hour:

bash
podman events --since 1h --until 10m --stream=false

Sample tail of the result:

output
2026-08-23 09:09:44.521498231 +0530 IST container init 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:44.539162406 +0530 IST container start 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:54.676088774 +0530 IST container stop 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:54.703959447 +0530 IST container died 97e33d58e12f... (name=evt-web, ...)
2026-08-23 09:09:55.04714762 +0530 IST container remove 97e33d58e12f... (name=evt-web, ...)

Workflow for a failure around 14:30: set --since to 14:20 and --until to 14:40 (RFC3339 or relative offsets from now), add --stream=false, then filter on the container name.


Stop streaming with --stream=false

Historical replay needs an explicit non-streaming flag on Podman 5.8.2:

bash
podman events --since 1h --stream=false

Default --stream is true, which keeps the process open after the last known event. Scripts, CI jobs, and article captures should always pass --stream=false when paired with --since or --until.


Filter by container name or ID

Scope output to one workload:

bash
podman run -d --name evt-filter docker.io/library/alpine:latest sleep 600

Stop the named container so the filter has stop and cleanup lines to match:

bash
podman stop evt-filter

Replay events scoped to that container name:

bash
podman events --since 5m --filter container=evt-filter --stream=false

Sample output:

output
2026-08-23 09:10:04.059701376 +0530 IST container create 0670922c3442... (name=evt-filter, ...)
2026-08-23 09:10:04.507099364 +0530 IST container init 0670922c3442... (name=evt-filter, ...)
2026-08-23 09:10:04.526167532 +0530 IST container start 0670922c3442... (name=evt-filter, ...)
2026-08-23 09:10:14.709572002 +0530 IST container died 0670922c3442... (name=evt-filter, ...)
2026-08-23 09:10:15.056257483 +0530 IST container cleanup 0670922c3442... (name=evt-filter, ...)

The filter accepts the container name or a short ID:

bash
podman events --since 5m --filter container=0670922c3442 --stream=false

Both forms returned the same lines in the lab.


Filter by event status

Focus on exits with event=died:

bash
podman run --name evt-die docker.io/library/alpine:latest false

List only died events from the last few minutes:

bash
podman events --since 5m --filter event=died --stream=false

Sample line (grep for the container name):

output
2026-08-23 09:10:20.175925214 +0530 IST container died e1cd6b75527d... (name=evt-die, ...)

Common container event statuses on Podman 5.8.2 include create, init, start, attach, stop, kill, died, cleanup, remove, restart, pause, unpause, exec, health_status, and others listed in podman-events(1). Docker-era docs often say die; Podman emits died — use that name in filters and scripts.


Filter by object type

Limit to one object class:

bash
podman events --since 5m --filter type=container --stream=false

Contrast with image-only events in the same window:

bash
podman events --since 5m --filter type=image --stream=false

Sample type=image lines:

output
2026-08-23 09:09:33.182276169 +0530 IST image pull d09203066f26... docker.io/library/alpine:latest
2026-08-23 09:10:26.408996205 +0530 IST image tag d09203066f26... localhost/evt-alpine:events-test

Valid type= values: container, pod, image, volume, network, secret, and system.


Combine multiple filters

Filters are ANDed. This query lists container deaths in the last day:

bash
podman events --since 24h --filter type=container --filter event=died --stream=false

Sample head:

output
2026-08-22 16:05:00.039374106 +0530 IST container died 9fbe81d6589e... (name=serene_taussig, ...)
2026-08-22 16:06:01.824062994 +0530 IST container died 103dbd7355fa... (name=podman-demo, ...)

Repeat --filter for each constraint. Narrow --since when the host has heavy churn.


Filter by pod

Pod-level filters show pod actions, not every member container by default:

bash
podman pod create --name evt-pod

Run a member container inside the pod:

bash
podman run -d --pod evt-pod --name evt-pod-c1 docker.io/library/alpine:latest sleep 600

Stop the pod to emit pod-level stop events:

bash
podman pod stop evt-pod

Replay with a pod filter:

bash
podman events --since 5m --filter pod=evt-pod --stream=false

Sample output:

output
2026-08-23 09:10:25.480410165 +0530 IST pod create d377211b3986... (name=evt-pod)
2026-08-23 09:10:26.233527018 +0530 IST pod stop d377211b3986... (name=evt-pod)

To see member container create and died lines, drop the pod filter or add --filter container=evt-pod-c1. Pod filters are useful when you care about pod stop/start; container filters drill into one member.


Filter by image

Track pull, tag, and remove for a reference:

bash
podman tag docker.io/library/alpine:latest localhost/evt-alpine:events-test

Query events tied to that local image reference:

bash
podman events --since 5m --filter image=localhost/evt-alpine:events-test --stream=false

Sample output:

output
2026-08-23 09:10:26.408996205 +0530 IST image tag d09203066f26... localhost/evt-alpine:events-test

Filter event=tag, event=pull, or event=remove when you need one image operation type. Image management workflows belong in the image articles — events only help you audit what already happened.


Format event output for scripts

Print selected fields with a Go template:

bash
podman events --since 1h --stream=false --format '{{.Time}} {{.Type}} {{.Status}} {{.Name}}'

Sample lines:

output
1787453365 container create stats-demo
1787453365 image pull docker.io/library/alpine:latest
1787453365 container init stats-demo
1787453365 container start stats-demo

The exact rendering of .Time may differ by Podman version and output path. On Podman 5.8.2, podman-events(1) documents .Time as the event timestamp string and .TimeNano as the integer nanosecond timestamp. For machine-readable timestamps, prefer JSON output or .TimeNano; do not assume .Time is always Unix seconds.

Emit JSON Lines for jq or log shippers:

bash
podman events --since 1h --stream=false --format json

Sample records (trimmed):

output
{"ID":"d09203066f26...","Name":"localhost/inspect-demo:latest","Status":"untag","time":1787452828,"Type":"image"}
{"ID":"3ab01c27109c...","Image":"docker.io/library/alpine:latest","Name":"stats-demo","Status":"create","time":1787453365,"Type":"container"}

Useful template fields: .Time, .TimeNano, .Type, .Status, .Name, .ID, .Image, .PodID, .ContainerExitCode, and .Attributes (JSON only). .TimeNano is the documented integer nanosecond field; JSON output uses a separate lowercase time field. .ContainerExitCode is populated on died events.


Find why a container died overnight

This is the workflow operators reach for when a service was running yesterday and is stopped now.

Confirm the container still exists (or existed recently):

bash
podman ps -a --filter name=evt-overnight

Start a stand-in container and kill it to simulate unattended failure:

bash
podman run -d --name evt-overnight docker.io/library/alpine:latest sleep 3600

Kill the stand-in to mimic an unattended failure:

bash
podman kill evt-overnight

Replay lifecycle events with exit codes:

bash
podman events --since 12h --filter container=evt-overnight --stream=false --format '{{.TimeNano}} {{.Status}} {{.ContainerExitCode}}'

Sample output:

output
1787456444000000000 create <nil>
1787456445000000000 init <nil>
1787456445000000000 start <nil>
1787456445000000000 kill <nil>
1787456445000000000 died 137

Exit code 137 means SIGKILL (128 + 9) — consistent with podman kill. A normal false command shows died 1.

Read what the application printed before exit with Podman logs:

bash
podman logs --since 12h evt-overnight

Pull final state and configuration:

bash
podman inspect --format 'Status={{.State.Status}} ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}' evt-overnight

Sample output:

output
Status=exited ExitCode=137 OOMKilled=false

Look for died, stop, kill, restart, remove, and health_status in the event stream. Events timestamp the lifecycle; logs explain stdout/stderr; inspect holds the final object state. Use all three when nobody was watching the terminal.


Journald events backend

When EventLogger is journald, Podman writes lifecycle records through systemd-journald. podman events remains the normal interface — you do not need a separate journal query for day-to-day debugging.

You can confirm journald is active with the podman info command shown at the top of this guide. Rootless and rootful Podman use separate runtime contexts, so run podman events as the same user/context that owns the affected container. sudo podman events should not be assumed to show another user's rootless Podman history.

This article does not teach journald administration. For log driver behavior and journalctl patterns on container stdout, see View and follow container logs.


File events backend

Set events_logger = "file" in Podman containers.conf to store events in a log file instead of journald. Related keys include events_logfile_path and events_logfile_max_size (default comment shows 1m).

On the lab host podman info reported an empty eventsLogfilePath because journald is the active backend. After switching to file, replay still uses podman events --since ... --stream=false — Podman reads the configured store.


Disable events (none)

Setting events_logger = "none" turns off event recording. podman events will have little or no history to replay. Do not disable event logging unless you accept losing unattended lifecycle reconstruction through Podman.


Health-check events

Containers with health probes can emit health_status events. On a host with frequent checks this can be noisy.

bash
podman run -d --name evt-health --health-cmd='test -f /tmp/ok || exit 1' --health-interval=2s --health-retries=2 docker.io/library/alpine:latest sleep 300

Filter the stream for health transition events:

bash
podman events --since 2m --filter event=health_status --stream=false

Sample lines (attributes trimmed):

output
2026-08-23 09:10:54.107083093 +0530 IST container health_status be9dfa62... (health_status=starting, ...)
2026-08-23 09:11:00.040947939 +0530 IST container health_status be9dfa62... (health_status=unhealthy, ...)

healthcheck_events in containers.conf controls whether these are logged (default comment: true). Probe configuration and failure actions are covered in Podman health checks — this section only notes that health transitions appear in the event stream.


Logs vs events vs inspect

Tool Answers
podman logs What the application printed to stdout/stderr
podman events What Podman lifecycle action occurred and when
podman inspect Current or final object configuration and state

Incident response often uses all three. Events reconstruct the timeline; logs show application messages before exit; inspect confirms exit code, OOM flags, and restart policy.


Cleanup

Remove lab containers and pods:

bash
podman rm -f evt-filter evt-die evt-die2 evt-overnight evt-health 2>/dev/null

Remove the lab pod if it still exists:

bash
podman pod rm -f evt-pod 2>/dev/null

Drop the local test image tag:

bash
podman rmi localhost/evt-alpine:events-test 2>/dev/null

Summary

podman events streams Podman lifecycle records — not application logs. Default mode waits for new activity; add --since and --stream=false to replay history for scripts or post-incident review. Filters narrow by container, event status, type, pod, and image; --format emits Go templates or JSON for automation.

When a container died while nobody was watching, replay died, stop, or kill events with --filter container=NAME, read .ContainerExitCode on died lines, then correlate Podman logs and podman inspect for the full picture. Check podman info --format '{{.Host.EventLogger}}' before assuming journald — file and none change what history is available.


References

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)