Podman Quadlet CLI: `install`, `list`, `print` and `rm`

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 5.6+ and systemd user sessions
Privilege Normal user with working rootless Podman on the lab host
Scope podman quadlet subcommands — install, list, print, and rm for single files, companion assets, application directories, and .quadlets bundles; list filters and formats; --reload-systemd, --replace, application removal semantics, CVE-2026-19730, and Podman 6 layout deltas. Assumes Quadlet unit files already exist. Does not teach every Quadlet type, systemd basics, or full [Container] directive reference.
Related guides Podman Quadlet container file
Podman Quadlet volume and network

You already write .container, .volume, and .network Quadlet files. Podman 5.6 added a dedicated CLI to install those declarations under the systemd search path, list what is on disk, print the stored source, and remove units without hand-copying files. The lab examples run as podtest with rootless Podman; the same subcommands apply to whichever Linux user owns the installation.


What podman quadlet does

podman quadlet manages Quadlet source files (and bundled assets). It does not start containers by itself.

Subcommand Role
podman quadlet install Copy or install Quadlet sources into the user's systemd Quadlet directory
podman quadlet list Show installed Quadlets, generated unit names, paths, status, and application membership
podman quadlet print Display the installed Quadlet source (alias: cat)
podman quadlet rm Remove installed Quadlets (and whole applications when applicable)

Lifecycle after install still belongs to systemd:

text
podman quadlet  →  install / update / remove declarations
systemctl       →  start / stop / enable generated services

Confirm the subcommand exists on your build before you script against it:

bash
podman quadlet --help

Sample output:

output
Allows users to manage Quadlets

Usage:
  podman quadlet [command]

Available Commands:
  install     Install a quadlet file or quadlet application
  list        List Quadlets
  print       Display the contents of a quadlet
  rm          Remove Quadlets

The management CLI requires Podman 5.6 or newer. Application layout and some flags changed again in Podman 6 — see the version table and Podman 6 section below.


Version and feature matrix

Feature Podman 5.6–5.8.x (lab: 5.8.2) Podman 6.0+
install / list / print / rm Yes Yes
Install directory as application Directory basename becomes .app metadata; files land flat under ~/.config/containers/systemd/ --application=NAME required; files install under .../systemd/NAME/ subdirectory
.quadlets multi-unit file Members share a .stack.app-style metadata file Use --application when you want a named application bundle
list --filter name only Check podman quadlet list --help on your build
Application removal Remove by application name or any member Quadlet; either removes the entire application --recursive required to remove an application directory
--replace CVE Affected 5.7.0–5.8.5 (lab: 5.8.2); fixed in 5.8.6 Fixed in 6.0.0

Run podman --version on the host you manage. Distro packages may backport the CVE fix without bumping the upstream minor version.


Install a single Quadlet file

Create a minimal web.container in a working directory:

ini
[Container]
Image=quay.io/podman/hello
ContainerName=cli-hello

[Install]
WantedBy=default.target

Install it for the current user:

bash
podman quadlet install web.container

Sample output:

output
/home/podtest/.config/containers/systemd/web.container

install prints each destination path. For a rootless user that is normally under ~/.config/containers/systemd/. By default, install also reloads systemd so the generator sees the new file immediately.

Confirm the registration:

bash
podman quadlet list

Sample output:

output
NAME           UNIT NAME    PATH ON DISK                                            STATUS         APPLICATION
web.container  web.service  /home/podtest/.config/containers/systemd/web.container  inactive/dead

The UNIT NAME column is what you pass to systemctl --user. Start or inspect it there — not through podman quadlet.


Install additional asset files

Quadlet containers often need env files or config next to the unit. Install the declaration and companions in one command:

bash
podman quadlet install demo.container demo.env demo-config.yml

Sample output:

output
/home/podtest/.config/containers/systemd/demo.container
/home/podtest/.config/containers/systemd/demo.env
/home/podtest/.config/containers/systemd/demo-config.yml

Reference companion files with paths relative to the installed Quadlet directory in the unit source:

ini
[Container]
Image=registry.access.redhat.com/ubi9/httpd-24
ContainerName=cli-demo
EnvironmentFile=demo.env

[Install]
WantedBy=default.target

Non-Quadlet files (demo.env, demo-config.yml) are copied beside the unit. They are not separate rows in podman quadlet list unless the CLI also treats them as Quadlet types.


Install a Quadlet application directory

When several units and assets belong together, point install at a directory. On Podman 5.8.2, a webapp/ folder on the lab host holds the container, volume, network, env file, and config sidecar.

bash
podman quadlet install ./webapp/

Sample output:

output
/home/podtest/.config/containers/systemd/data.volume
/home/podtest/.config/containers/systemd/web.env
/home/podtest/.config/containers/systemd/app-config.yml
/home/podtest/.config/containers/systemd/app.network
/home/podtest/.config/containers/systemd/appweb.container

Podman treats every file installed from that directory as one application. List again to see the shared APPLICATION value:

bash
podman quadlet list

Sample output:

output
NAME              UNIT NAME           PATH ON DISK                                           STATUS         APPLICATION
appweb.container  appweb.service      /home/podtest/.config/containers/systemd/appweb.container  inactive/dead  .webapp.app
data.volume       data-volume.service /home/podtest/.config/containers/systemd/data.volume       inactive/dead  .webapp.app

On Podman 6.0 and later, directory installs require an explicit application name and place files under a subdirectory — see Podman 6 Quadlet application layout.


.quadlets multi-unit file

A .quadlets file packs several units in one install source. Each section needs a # FileName= comment and a --- delimiter between sections:

ini
# FileName=stack-web
[Container]
Image=quay.io/podman/hello
ContainerName=cli-stack-web

[Install]
WantedBy=default.target
---
# FileName=stack-data
[Volume]
---
# FileName=stack-net
[Network]
NetworkName=cli-stack-net

Install the bundle:

bash
podman quadlet install stack.quadlets

Sample output:

output
/home/podtest/.config/containers/systemd/stack-web.container
/home/podtest/.config/containers/systemd/stack-data.volume
/home/podtest/.config/containers/systemd/stack-net.network

The .quadlets extension is required — other extensions are treated as a single Quadlet or a plain asset. On 5.8.2 the installed members share application metadata (for example .stack.app in the APPLICATION column). Podman 6 may require --application to name that bundle explicitly.


List installed Quadlets

list is the inventory view across everything installed for the current user:

bash
podman quadlet list

Columns map to automation-friendly fields:

  • NAME — Quadlet filename (web.container)
  • UNIT NAME — generated systemd unit (web.service)
  • PATH ON DISK — installed source location
  • STATUS — systemd unit state (inactive/dead, active/running, Not loaded, …)
  • APPLICATION — application metadata when the unit belongs to a bundle

Filter by name on 5.8.2:

bash
podman quadlet list --filter 'name=stack*'

Sample output:

output
NAME                 UNIT NAME                  PATH ON DISK                                                  STATUS         APPLICATION
stack-data.volume    stack-data-volume.service  /home/podtest/.config/containers/systemd/stack-data.volume    inactive/dead  .stack.app
stack-net.network    stack-net-network.service  /home/podtest/.config/containers/systemd/stack-net.network    inactive/dead  .stack.app
stack-web.container  stack-web.service          /home/podtest/.config/containers/systemd/stack-web.container  inactive/dead  .stack.app

status and pod filters are not valid on 5.8.2 — the CLI returns an error if you try them. Use podman quadlet list --help on newer builds before scripting those filters.


Format podman quadlet list output

For scripts, trim the table with a Go template:

bash
podman quadlet list --format '{{.Name}} {{.Status}}'

Sample output:

output
NAME STATUS
app.network inactive/dead
demo.container inactive/dead
stack-web.container inactive/dead

JSON output is also available when your build supports it:

bash
podman quadlet list --format json

The first object includes Name, UnitName, Path, Status, and App fields — enough for Ansible or CI checks without parsing the default table.


print shows the Quadlet source Podman installed — comments and all:

bash
podman quadlet print web.container

cat is an alias:

bash
podman quadlet cat web.container

Sample output:

output
[Container]
Image=quay.io/podman/hello
ContainerName=cli-hello-v2

[Install]
WantedBy=default.target

Do not confuse this with the generated systemd unit. Compare:

Command Shows
podman quadlet print web.container Installed .container source under ~/.config/containers/systemd/
systemctl --user cat web.service Generated .service unit from the Quadlet generator (includes [Unit], ExecStart=, cgroup settings, …)

Ask systemd for the generated unit transcript:

bash
systemctl --user cat web.service

Sample output:

output
# /run/user/1014/systemd/generator/web.service
# Automatically generated by /usr/lib/systemd/user-generators/podman-user-generator
[X-Container]
Image=quay.io/podman/hello
ContainerName=cli-hello-v2

Use print after install --replace to confirm what landed on disk. Use systemctl cat when you need to debug how the generator translated that source.


Remove a Quadlet

Remove one installed declaration:

bash
podman quadlet rm web.container

Sample output:

output
web.container

By default, rm reloads systemd after removal (same default as install).

If the unit is still running, rm may fail until you stop it or pass --force:

bash
podman quadlet rm --force web.container

--all removes every Quadlet for the current user. Pair bulk scripts with --reload-systemd=false when you remove many files in one transaction.


Remove a Quadlet application

On Podman 5.8.2, removing any Quadlet that belongs to an application deletes the entire application — companion volumes, networks, and asset files included. Remove one member:

bash
podman quadlet rm appweb.container

You can also remove the application by passing the application identifier shown in the APPLICATION column of podman quadlet list:

bash
podman quadlet rm .webapp.app

Either command removes the same bundle. Sample output:

output
appweb.container
app.network
data.volume

After removal, podman quadlet list no longer shows the .webapp.app members.

Podman 6.0 changes layout: application directories live in named subfolders and podman quadlet rm --recursive APPNAME removes the whole tree. Check podman quadlet rm --help on the target version.


--reload-systemd

Both install and rm reload systemd by default (--reload-systemd=true). To batch several installs before a single reload:

bash
podman quadlet install --reload-systemd=false ping.container

Until you reload manually, list may show Not loaded for the new unit:

output
NAME            UNIT NAME     PATH ON DISK                                             STATUS      APPLICATION
ping.container  ping.service  /home/podtest/.config/containers/systemd/ping.container  Not loaded

Apply the generator queue yourself:

bash
systemctl --user daemon-reload

That pattern suits scripts installing a pod, volume, and network before starting any of the generated services.


Update an installed Quadlet with --replace

To overwrite an existing installation:

bash
podman quadlet install --replace web.container

Sample output:

output
/home/podtest/.config/containers/systemd/web.container

Without --replace, a second install of the same name fails rather than silently clobbering the file.


CVE-2026-19730: --replace could retain old content

IMPORTANT
On affected Podman builds, install --replace could write a shorter file without truncating the previous destination. Directives you removed from the new source might still exist at the end of the installed file, and Podman would report success.

Conceptual example of the risk:

Old installed file:

ini
Volume=/host/secrets:/secrets
AddCapability=NET_ADMIN

New source removes both lines. A vulnerable --replace might leave those lines on disk.

Affected: Podman 5.7.0 through 5.8.5 (the lab runs 5.8.2). Fixed in: Podman 5.8.6 and 6.0.0 (or your distribution's patched package — verify with podman --version and vendor security advisories).

If you are stuck on a vulnerable build:

  • Remove the destination file manually, then install again
  • Or copy the file yourself and verify with podman quadlet print instead of trusting --replace

Do not use --replace for security-sensitive unit edits until you confirm a fixed package.


Verify the installed Quadlet after replacement

Even on a fixed release, make update workflows explicit:

bash
podman quadlet print web.container

Confirm the on-disk source matches your intent, then reload:

bash
systemctl --user daemon-reload

Inspect how the generator interpreted the change:

bash
systemctl --user cat web.service

That three-step loop — print, daemon-reload, systemctl cat — keeps CLI updates visible before you restart the workload.


Podman 6 Quadlet application layout

Podman 5.8.2 on the lab host installs application members flat under ~/.config/containers/systemd/ and tracks membership in hidden .app metadata files (for example .webapp.app listing appweb.container, data.volume, and assets).

Podman 6.0 changes application handling:

  • Directory installs require --application=NAME
  • Installed files move under ~/.config/containers/systemd/NAME/
  • Subdirectories in the Quadlet search path are treated as applications by the generator — .app marker files go away
  • podman quadlet rm expects --recursive when removing an application directory

I did not run Podman 6 on this lab host. After upgrading, compare layouts with:

bash
podman quadlet list

and inspect ~/.config/containers/systemd/ — you should see per-application subdirectories instead of flat files plus .app metadata. Re-run your install playbooks; paths referenced from [Container] sections may need updating if assets moved into a subdirectory.


CLI vs manual copy

Manual copy to ~/.config/containers/systemd/ podman quadlet install
Transparent — you choose the exact path Installs to the canonical Quadlet directory for the current user
Fits config-management repos that already sync files Bundles application directories and .quadlets multi-unit sources
Works on any Podman with Quadlet support Requires Podman 5.6+
You run systemctl --user daemon-reload yourself Reloads systemd by default
No --replace CVE surface from the CLI Provides --replace, list, print, and rm for day-to-day edits

Configuration management (Ansible, GitOps, golden images) will keep copying files directly — that remains valid. The CLI shines when a user or installer ships a Quadlet application from a directory, URL, or .quadlets bundle without writing custom copy logic.


Troubleshooting

Symptom Likely cause Fix
podman quadlet: command not found Podman older than 5.6 Upgrade Podman or install units manually
Not loaded in list STATUS Deferred systemd reload systemctl --user daemon-reload
refusing to overwrite on install Name already installed podman quadlet rm UNIT or install --replace on a patched build
sudo systemctl sees nothing Rootless install Use systemctl --user as the same user
Removed lines still in print output CVE-2026-19730 on affected build (5.7.0–5.8.5) Upgrade to 5.8.6, 6.0.0, or a vendor-patched package; or remove file manually before reinstall
status is not a valid filter Filter not on 5.8.2 Use name= only, or upgrade and re-check --help

Generator and runtime errors after a correct install belong in Podman Quadlet troubleshooting.


References


Summary

podman quadlet adds install, list, print, and rm on top of the Quadlet workflow you already know from Podman Quadlet with systemd. You install sources into the user's systemd path, confirm them with list and print, and hand runtime to systemctl --user — the CLI never replaces systemd for start and stop.

The lab walked single-file install, companion assets, directory applications, and .quadlets bundles on Podman 5.8.2. Application membership shows up in the APPLICATION column and matters for removal: deleting one member or passing that column's identifier removes the whole bundle. Treat podman quadlet print and systemctl --user cat as complementary views — source file versus generated unit.

Before you rely on install --replace, check your package against CVE-2026-19730 and verify with print after every update. When you move to Podman 6, expect application directories instead of flat files with .app metadata — re-list installed units and adjust asset paths after upgrade. For rootless path and linger detail, pair this page with Rootless Podman Quadlet.


Frequently Asked Questions

1. Does podman quadlet replace systemctl for Quadlet workloads?

No. podman quadlet installs and removes Quadlet source files under the configured systemd path. systemctl or systemctl --user still starts, stops, enables, and inspects the generated services after installation.

2. Which Podman version adds the podman quadlet subcommand?

The install, list, print, and rm subcommands ship in Podman 5.6 and later. Run podman quadlet --help before scripting on older distro packages.

3. What happens when I remove one Quadlet that belongs to an application?

On Podman 5.8.x, removing any member of an installed application deletes the entire application group, including companion asset files tracked in the .app metadata file. Plan removals accordingly.

4. Is --replace safe on every Podman build?

No. Podman 5.7.0 through 5.8.5 are affected upstream. The fix is in 5.8.6, and Podman 6.0.0 includes the fix. Upgrade to a patched package, or remove the destination manually and verify with podman quadlet print before relying on --replace.

5. Why does podman quadlet list show Not loaded after install?

install reloads systemd by default. If you passed --reload-systemd=false, the generator has not picked up the new file yet. Run systemctl --user daemon-reload, then list or start the unit again.
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)