Start, Stop and Restart Podman Containers

Tested on Red Hat Enterprise Linux 10.2 (Coughlan)
Package podman-5.8.2-5.el10_2.x86_64
Applies to Any Linux host with Podman installed
Privilege Rootful examples on the lab host; flags behave the same rootless unless noted
Scope Controlling existing container state — start, stop, restart, kill, pause, unpause, wait, stop timeout, restart policies, and podman-restart.service. Does not cover podman run options, Quadlet setup, log troubleshooting, or diagnosing immediate-exit root causes.
Related guides Install Podman on RHEL

You already have containers on disk; this guide covers what to run when you need one running, stopped, restarted, or paused. Creation flags and image pulls belong in Run containers with podman run — here the main demo container is lc-demo, with lc-web and lc-cache for multi-container examples.


Check the container state first

Before changing state, list every container Podman knows about:

bash
podman ps -a --filter name=lc- --format "table {{.Names}}\t{{.Status}}\t{{.State}}"

Sample output:

output
NAMES            STATUS                     STATE
lc-demo          Created                    created
lc-created       Created                    created
lc-web           Up 2 minutes               running
lc-cache         Up 2 minutes               running
lc-wait          Exited (0) 3 minutes ago   exited
lc-pause-demo    Paused                     paused

The STATUS and STATE columns tell you which lifecycle command applies:

  • running / Up — use stop, restart, kill, or pause
  • exited / Exited — use start or restart
  • paused / Paused — use unpause (not start)
  • created / Created — use start (container exists but PID 1 never ran)

For wider filtering and column formatting, see List containers with podman ps.


Start a stopped Podman container

lc-demo was created with podman create and is in Created state. Start it with:

bash
podman start lc-demo

The command prints the container ID when the start succeeds.

Confirm it is running:

bash
podman ps --filter name=lc-demo --format "{{.Names}} {{.Status}}"

Sample output:

output
lc-demo Up 1 second

podman start reuses the existing container record — same name, image, mounts, and labels as when it was created. It does not pull a fresh image or allocate a new name.

text
podman run   = create + start a new container
podman start = start an existing container

To start every stopped container on the host:

bash
podman start --all

Podman prints one ID per container it starts. On a busy host, combine with filters from podman ps when you only want a subset.

Add -a to start and attach to the container main process stdout/stderr:

bash
podman start -a lc-demo

Your shell stays connected until the main process exits — useful for one-shot jobs you created earlier with podman create. For attaching to a container that is already running, use podman attach instead; this article does not cover attach in depth.


Stop a Podman container gracefully

podman stop asks the main process to exit before forcing termination:

bash
podman stop lc-demo

Sample output on this lab host:

output
time="2026-08-22T21:08:00+05:30" level=warning msg="StopSignal SIGTERM failed to stop container lc-demo in 10 seconds, resorting to SIGKILL"
lc-demo

The shutdown sequence is:

  1. Podman sends the configured stop signal (SIGTERM by default, unless the image or podman create/run set --stop-signal).
  2. Podman waits for the stop timeout (10 seconds by default on Podman 5.8.2).
  3. If the process is still running, Podman sends SIGKILL.

sleep in minimal images often ignores SIGTERM, which is why the lab shows the SIGKILL escalation warning. Application images with a proper PID 1 handler usually exit on the first signal without reaching step 3.

Verify the container stopped:

bash
podman ps -a --filter name=lc-demo --format "{{.Names}} {{.Status}}"

Sample output:

output
lc-demo Exited (137) 2 seconds ago

Exit code 137 means the process received SIGKILL (128 + 9). That is expected when graceful shutdown timed out.

podman stop is not the same as podman kill: stop waits and escalates; kill sends a signal immediately (SIGKILL by default). The comparison section below covers when to use each.


Change the stop timeout

lc-web must be running before you can time a stop. Start it if you stopped it in the previous section:

bash
podman start lc-web

Shorten the grace period to two seconds:

bash
podman stop --time 2 lc-web

On this host the command took about three seconds end-to-end and printed:

output
time="2026-08-22T21:08:05+05:30" level=warning msg="StopSignal SIGTERM failed to stop container lc-web in 2 seconds, resorting to SIGKILL"
lc-web

--time only changes how long Podman waits before SIGKILL — it does not change which signal is sent first. The default timeout is 10 seconds on Podman 5.8.2 (podman stop --help shows default 10).

Pass -1 where your Podman build supports it to wait indefinitely for the process to exit after the stop signal. Use that sparingly on production hosts; a hung PID 1 will block shutdown until you intervene manually.


Restart a Podman container

Bring lc-web back up if the stop-timeout demo left it exited:

bash
podman start lc-web

podman restart stops a running container and starts it again with the same configuration:

bash
podman restart lc-web

Sample output:

output
time="2026-08-22T21:08:18+05:30" level=warning msg="StopSignal SIGTERM failed to stop container lc-web in 10 seconds, resorting to SIGKILL"
lc-web

On a container that is already stopped, restart behaves like start. Stop lc-cache first:

bash
podman stop lc-cache

Then restart without a separate start:

bash
podman restart lc-cache

Confirm it came back up:

bash
podman ps --filter name=lc-cache --format "{{.Names}} {{.Status}}"

Sample output:

output
lc-cache Up 2 seconds

Restart all containers, including starting containers that are currently stopped:

bash
podman restart --all

Be careful with --all: it is not limited to currently running containers. If you only want a subset, use names or --filter.

--time on podman restart applies the same stop-timeout semantics as podman stop before the start phase.


Restart multiple or filtered containers

Name several containers in one command:

bash
podman restart lc-web lc-cache

Podman restarts each name in sequence and prints its ID.

Filter by label when names are not enough (lc-web was created with --label app=demo):

bash
podman restart --filter label=app=demo

Sample output:

output
c7221265ce256dbd88f589e37eff28367fabeaebb7c5559d68adb5dea075e424

Only lc-web matched app=demo in this lab. podman restart does not accept --format; check results with podman ps afterward.


podman stop vs podman kill

Command Default behavior
podman stop Configured stop signal (usually SIGTERM), then SIGKILL after timeout
podman kill SIGKILL immediately
podman restart Stop phase then start the same container

Create a signal-trap container for the kill demo:

bash
podman run -d --name lc-signal registry.access.redhat.com/ubi9/ubi-minimal sh -c 'trap "exit 0" TERM; sleep 600'

Send the default SIGKILL:

bash
podman kill lc-signal

Check how it exited:

bash
podman ps -a --filter name=lc-signal --format "{{.Names}} {{.Status}}"

Sample output:

output
lc-signal Exited (137) 2 seconds ago

Exit 137 again — SIGKILL with no grace period.

Send a different signal when you need controlled delivery without the stop timeout. Recreate the container:

bash
podman run -d --name lc-signal registry.access.redhat.com/ubi9/ubi-minimal sh -c 'trap "exit 0" TERM; sleep 600'

Deliver SIGTERM instead of the kill default:

bash
podman kill --signal TERM lc-signal

podman kill --signal TERM sends SIGTERM immediately instead of the default SIGKILL. Unlike podman stop, Podman does not wait for a stop timeout and then escalate; what happens next depends on how the container's PID 1 handles SIGTERM.

Use podman stop for normal application shutdown. Reserve podman kill for hung containers or when you deliberately need to deliver a specific signal now.


Pause and unpause a Podman container

podman pause freezes container processes without terminating them:

bash
podman pause lc-web

Check the status column:

bash
podman ps --filter name=lc-web

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND     CREATED        STATUS  PORTS       NAMES
f1e749ebb335  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600   5 minutes ago  Paused              lc-web

The container still exists with the same ID and writable layer; only execution is suspended.

Resume it with:

bash
podman unpause lc-web

After unpause, status should return to Up:

bash
podman ps --filter name=lc-web --format "{{.Names}} {{.Status}}"

Sample output:

output
lc-web Up 3 seconds

Pause is not a substitute for stop — use pause when you need the process table frozen in place and stop when you want the main process to exit.


Wait for a container to exit with podman wait

podman wait blocks until a container stops and prints its exit code:

bash
podman run --name lc-wait registry.access.redhat.com/ubi9/ubi-minimal echo hello-wait

The container exits immediately after printing. Wait on it:

bash
podman wait lc-wait

Sample output:

output
0

Exit code 0 means the main process succeeded.

Wait on a condition instead of exit alone:

bash
podman wait --condition=stopped lc-wait

Sample output:

output
0

Supported conditions on Podman 5.8.2 include running, stopped, exited, healthy, unhealthy, and removing. Create a health-checked container to try the healthy condition:

bash
podman run -d --name lc-health --health-cmd "test -f /tmp/healthy || exit 1" --health-interval 2s registry.access.redhat.com/ubi9/ubi-minimal sh -c "touch /tmp/healthy; sleep 600"

Wait until the probe reports healthy:

bash
podman wait --condition=healthy lc-health

Run that while lc-health is still starting and it returns when the probe passes. For a podman run --rm container, normal wait completion does not guarantee removal has finished — use --condition=removing when your script must wait for the record to disappear.


Configure automatic restart policies

Restart policy is set at create time with --restart on podman run or podman create. The four common values are:

  • no — never restart automatically (default)
  • on-failure[:max_retries] — restart after a non-zero process exit
  • always — restart after process exit regardless of exit status
  • unless-stopped — restart after process exit unless explicitly stopped; unlike always, an explicitly stopped container is also skipped by podman-restart.service after reboot

Restart policies do not take effect when you explicitly stop the container with podman stop or podman kill. The main difference between always and unless-stopped after that explicit stop is boot behavior: always containers are eligible again after reboot, while unless-stopped containers stay excluded until you podman start them manually.

Restart policy reacts to process exit while the host keeps running. It is not the same command as podman restart, which you invoke manually.

Example with on-failure:

bash
podman run -d --name lc-restart-demo --restart=on-failure registry.access.redhat.com/ubi9/ubi-minimal sh -c 'exit 1'

After a few seconds, check restart count:

bash
podman ps -a --filter name=lc-restart-demo --format "{{.Names}} {{.Status}} restarts={{.Restarts}}"

Sample output:

output
lc-restart-demo Exited (1) 2 seconds ago restarts=2

Inspect the stored policy:

bash
podman inspect lc-restart-demo --format '{{.HostConfig.RestartPolicy.Name}}'

Sample output:

output
on-failure

An explicit podman stop or podman kill prevents automatic restart for policies that respect manual shutdown. on-failure only retries after non-zero exits, not after you stop the container yourself.


Restart Podman containers after reboot

Host reboot is a separate problem from process exit. Podman ships podman-restart.service, which runs at boot:

text
ExecStart=/usr/bin/podman start --all --filter should-start-on-boot=true

Containers whose restart policy maps to boot start — for example always — appear in that filter:

bash
podman ps -a --filter should-start-on-boot=true --format "{{.Names}} {{.Status}}"

Sample output:

output
lc-always Up 30 seconds

Enable the unit on hosts where you rely on CLI-created containers coming back after reboot:

bash
systemctl enable --now podman-restart.service

On this lab host the unit exists but is disabled until you enable it. Rootless users need a user systemd session (loginctl enable-linger) for an equivalent user-level restart path.

Goal Mechanism
Process dies while host stays up Podman --restart policy
Host reboots podman-restart.service + restart policy (should-start-on-boot)
systemd owns the workload Restart= on the systemd/Quadlet unit

always containers are generally eligible to start on boot even after you previously stopped them manually. unless-stopped remembers that explicit stop and skips those containers in podman-restart.service after reboot until you podman start them again.


Restart policy vs Quadlet and systemd

When systemd or Quadlet generates a unit for your container, systemd should own restart behavior:

text
Restart=on-failure

in the unit file — not an additional --restart=always on the same workload without a reason.

Standalone CLI containers can use Podman restart policy plus podman-restart.service for boot survival. Production services usually move to Podman Quadlet and systemd so systemctl restart and journal logging apply. See also Podman auto-update with Quadlet for image refresh and Container stops after logout when rootless sessions end at SSH disconnect.


Common lifecycle errors

Symptom Likely cause Fix
no container with name or ID "…" found Container removed or wrong name Run podman ps -a; recreate if needed
podman stop on already-stopped container Idempotent stop on Podman 5.8.2 — prints the name/ID and succeeds No action required; verify with podman ps -a
Stop hangs then SIGKILL warning PID 1 ignores the stop signal Fix the app signal handler; shorten or lengthen --time; avoid kill for routine shutdown
Container restarts in a loop on-failure or always policy with crashing command Inspect policy with podman inspect; fix the command — see Container exits immediately
Containers missing after reboot podman-restart.service disabled or unless-stopped after manual stop Enable the service; use always or start manually; check linger for rootless

Starting a removed container fails immediately:

bash
podman start lc-ghost

Sample output:

output
Error: no container with name or ID "lc-ghost" found: no such container

Stopping an already-stopped container on Podman 5.8.2 prints the container name and exits successfully:

bash
podman stop lc-demo

Sample output:

output
lc-demo

References


Summary

Starting, stopping, and restarting existing containers is separate from creating them. podman start brings back a defined container; podman run always creates a new one. podman stop sends the configured stop signal, waits up to the timeout (10 seconds by default on Podman 5.8.2), and escalates to SIGKILL when the process does not exit — which is why minimal sleep demos often show a warning before exit code 137.

podman kill skips the grace period unless you pass --signal. podman pause and podman unpause freeze and resume processes without destroying the container. podman wait blocks for exit codes or conditions such as healthy and stopped, which helps scripts coordinate on container state rather than polling podman ps.

Restart policy handles process death while the host stays up; podman-restart.service plus should-start-on-boot handles eligible containers after reboot. When systemd or Quadlet manages the workload, prefer Restart= on the unit over layering Podman --restart on the same service. List state with podman ps -a before you issue lifecycle commands so you match the right verb to running, exited, paused, or created.

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)