Manage Containers with Podman Quadlet and systemd

Define one small container declaratively and let systemd manage its lifecycle through Podman Quadlet instead of jumping straight to a bigger orchestration tool.

PodmanQuadletsystemd
Illustrated guide cover for Manage Containers with Podman Quadlet and systemd
Podman • Quadlet • systemd
What you learn

How to place a .container file in the right Quadlet path, reload systemd, start the generated service, and verify the container through normal service tools.

Best for

Operators who want to run one or two containers with clear systemd lifecycle control without turning the first step into a migration project.

Risk to watch

The common mistake is turning a simple one-container guide into a broad Docker-versus-Podman debate or a pseudo-orchestrator design.

Before you begin

  • A Linux host with Podman installed.
  • Systemd available on the host.
  • Comfort with basic service management commands.
  • A willingness to start with one simple service instead of a full stack.

Podman Quadlet works by using a systemd generator to translate declarative files such as .container and .volume into normal service units. That makes it a strong fit for small, Linux-native container management where you want the service lifecycle to stay legible.

Expected outcome: By the end, one Quadlet-managed container service is defined on disk, started by systemd, and easy to inspect with the same service tools you already use elsewhere on Linux.

Step 1: Pick the correct Quadlet search path

Podman documents different search paths for rootful and rootless Quadlet files. For a first system-wide service, keep it rootful and use:

/etc/containers/systemd/

That avoids mixing the first lesson with per-user service behavior. If you later want rootless Quadlet, Podman also documents user paths such as ~/.config/containers/systemd/.

Verify Podman itself is healthy first:

podman info --format '{{.Host.CgroupsVersion}}'
podman --version

Quadlet requires cgroup v2 according to the Podman docs, so confirm that before you blame the unit file.

Step 2: Write one small .container unit

Create a simple web test service. This example keeps the first unit intentionally small:

sudo mkdir -p /etc/containers/systemd
sudo nano /etc/containers/systemd/whoami-demo.container

Example file:

[Unit]
Description=Whoami demo container

[Container]
ContainerName=whoami-demo
Image=docker.io/traefik/whoami:v1.10
PublishPort=8080:80

[Service]
Restart=always

[Install]
WantedBy=multi-user.target

The important idea is not the specific image. It is the shape of the file: a normal unit with a Quadlet-specific [Container] section. Podman handles that section, and systemd handles the rest.

Step 3: Reload systemd and start the generated service

Reload systemd so the generator sees the new file, then start the generated service:

sudo systemctl daemon-reload
sudo systemctl start whoami-demo.service
sudo systemctl status whoami-demo.service

Podman notes that Quadlet-generated services are transient from systemd's point of view, so the generator applies the [Install] section during generation rather than relying on ordinary systemctl enable semantics later. That is why the WantedBy= line still matters.

Step 4: Verify the container and service state

Check both the service view and the container view:

sudo systemctl status whoami-demo.service
sudo journalctl -u whoami-demo.service -b
sudo podman ps
curl http://127.0.0.1:8080

If the response comes back, the generated service is working and the container port is published as expected.

When you edit the Quadlet file later, repeat the same pattern:

sudo systemctl daemon-reload
sudo systemctl restart whoami-demo.service

Rollback and recovery notes

If the unit is wrong or you want to remove it, stop the service and remove the source file:

sudo systemctl stop whoami-demo.service
sudo rm /etc/containers/systemd/whoami-demo.container
sudo systemctl daemon-reload

Keep the first rollback boring. Delete the one service, reload systemd, and confirm it is gone before you experiment with additional Quadlet types such as volumes or networks.

Troubleshooting common Quadlet mistakes

systemctl cannot find the generated service.
There is often a syntax error in the Quadlet file, or the file is in the wrong search path. The Podman examples suggest using systemd verification tools when the service does not appear.

The host uses the wrong path type.
Make sure you are not mixing rootful and rootless search paths. Keep the first guide in one lane.

The container starts but never becomes useful.
Inspect journalctl and podman ps. The service layer may be fine while the container image or command is wrong.

You are trying to turn this into Compose replacement day one.
Do not. Learn the single-container path first, then add volumes, networks, or more services only if the host actually benefits from the shift.

What to do next: If you want to stay in the Docker lane instead of changing runtimes, the next practical day-two admin upgrade is using safer remote control patterns. Pair this guide with Use Docker Contexts over SSH for Safer Remote Admin.