| 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:
podman quadlet → install / update / remove declarations
systemctl → start / stop / enable generated servicesConfirm the subcommand exists on your build before you script against it:
podman quadlet --helpSample 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 QuadletsThe 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:
[Container]
Image=quay.io/podman/hello
ContainerName=cli-hello
[Install]
WantedBy=default.targetInstall it for the current user:
podman quadlet install web.containerSample output:
/home/podtest/.config/containers/systemd/web.containerinstall 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:
podman quadlet listSample output:
NAME UNIT NAME PATH ON DISK STATUS APPLICATION
web.container web.service /home/podtest/.config/containers/systemd/web.container inactive/deadThe 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:
podman quadlet install demo.container demo.env demo-config.ymlSample output:
/home/podtest/.config/containers/systemd/demo.container
/home/podtest/.config/containers/systemd/demo.env
/home/podtest/.config/containers/systemd/demo-config.ymlReference companion files with paths relative to the installed Quadlet directory in the unit source:
[Container]
Image=registry.access.redhat.com/ubi9/httpd-24
ContainerName=cli-demo
EnvironmentFile=demo.env
[Install]
WantedBy=default.targetNon-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.
podman quadlet install ./webapp/Sample 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.containerPodman treats every file installed from that directory as one application. List again to see the shared APPLICATION value:
podman quadlet listSample 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.appOn 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:
# 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-netInstall the bundle:
podman quadlet install stack.quadletsSample output:
/home/podtest/.config/containers/systemd/stack-web.container
/home/podtest/.config/containers/systemd/stack-data.volume
/home/podtest/.config/containers/systemd/stack-net.networkThe .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:
podman quadlet listColumns 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:
podman quadlet list --filter 'name=stack*'Sample 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.appstatus 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:
podman quadlet list --format '{{.Name}} {{.Status}}'Sample output:
NAME STATUS
app.network inactive/dead
demo.container inactive/dead
stack-web.container inactive/deadJSON output is also available when your build supports it:
podman quadlet list --format jsonThe first object includes Name, UnitName, Path, Status, and App fields — enough for Ansible or CI checks without parsing the default table.
Print an installed Quadlet
print shows the Quadlet source Podman installed — comments and all:
podman quadlet print web.containercat is an alias:
podman quadlet cat web.containerSample output:
[Container]
Image=quay.io/podman/hello
ContainerName=cli-hello-v2
[Install]
WantedBy=default.targetDo 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:
systemctl --user cat web.serviceSample 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-v2Use 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:
podman quadlet rm web.containerSample output:
web.containerBy 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:
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:
podman quadlet rm appweb.containerYou can also remove the application by passing the application identifier shown in the APPLICATION column of podman quadlet list:
podman quadlet rm .webapp.appEither command removes the same bundle. Sample output:
appweb.container
app.network
data.volumeAfter 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:
podman quadlet install --reload-systemd=false ping.containerUntil you reload manually, list may show Not loaded for the new unit:
NAME UNIT NAME PATH ON DISK STATUS APPLICATION
ping.container ping.service /home/podtest/.config/containers/systemd/ping.container Not loadedApply the generator queue yourself:
systemctl --user daemon-reloadThat 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:
podman quadlet install --replace web.containerSample output:
/home/podtest/.config/containers/systemd/web.containerWithout --replace, a second install of the same name fails rather than silently clobbering the file.
CVE-2026-19730: --replace could retain old content
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:
Volume=/host/secrets:/secrets
AddCapability=NET_ADMINNew 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
installagain - Or copy the file yourself and verify with
podman quadlet printinstead 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:
podman quadlet print web.containerConfirm the on-disk source matches your intent, then reload:
systemctl --user daemon-reloadInspect how the generator interpreted the change:
systemctl --user cat web.serviceThat 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 —
.appmarker files go away podman quadlet rmexpects--recursivewhen removing an application directory
I did not run Podman 6 on this lab host. After upgrading, compare layouts with:
podman quadlet listand 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
- podman-quadlet(1) — subcommand overview
- podman-quadlet-install(1) — install options and examples
- podman-quadlet-list(1) — filters and format placeholders
- podman-systemd.unit(5) — Quadlet file syntax
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.

