Quadlets in Practice: Running Containers Like Regular Services

Quadlets in Practice: Running Containers Like Regular Services
By Matthias Petermann / on 18.07.2026

Recently, I was tasked with building a dedicated monitoring stack consisting of Grafana, Prometheus, Loki, and Alertmanager. The setup was a RHEL 9 VM, with a clear goal: build operations on solid standard technologies with as few moving parts as possible.

Exactly in situations like this, practice shows what really matters: not as many features as possible, but a calm and robust operating mode.

ℹ️ Quick explanation: What is a Quadlet?
A Quadlet is a declarative file (for example, .container) from which systemd automatically generates a service unit when loading. Result: containers can be operated like regular services via systemctl and journalctl.

Containers are quick to start technically, but in day-to-day operations they are often unnecessarily fragmented: different startup logic, different logs, different runbooks, different on-call paths.

For me, Quadlets were exactly the counter-design here, even though I had not had them on my radar until then. They make it possible to run containers like regular services. For the operations team, two tools then become decisive in practice: systemctl and journalctl.

That makes a major difference, especially when a small team has to support very heterogeneous applications and cover on-call duty at the same time.

Even more important, Quadlets act like a stable contract in operations. Even if details change on the underlying operating system, the declarative service description remains. Especially during major upgrades, this helps re-establish a clearly defined target state after reboot or reprovisioning.

ℹ️ Operations platforms: stability comes from simplicity

For operations platforms, one simple principle applies: the platform itself must not become the breaking point. If deployments become opaque, depend on the availability of external services, configurations are hard to understand, and too many moving parts accumulate, not only does effort increase, but operational risk increases as well.

The monitoring example makes this especially visible, but it stands for many platform areas. Wherever systems must run reliably around the clock, clear ownership, reproducible procedures, and robust standard mechanisms provide the biggest leverage.

For monitoring specifically, the alarm-system analogy fits well: resilience against external influences and as much independence as possible from third-party services are core quality traits, for example through independent power supply.


What are Quadlets?

Quadlets are declarative files (for example .container, .network, .volume, .image) from which systemd units are generated automatically when loaded.

Instead of maintaining long podman run commands or custom wrapper scripts, you describe the desired state in files. systemd then takes over the familiar lifecycle management.

A minimal example:

# /etc/containers/systemd/web.container
[Unit]
Description=Web container
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/library/nginx:alpine
ContainerName=web
PublishPort=8080:80

[Service]
Restart=always

[Install]
WantedBy=multi-user.target

After that, day-to-day operations run through standard commands:

systemctl daemon-reload
systemctl enable --now web.service
systemctl status web.service
journalctl -u web.service -f
ℹ️ Core operational benefit

Quadlets reduce not only configuration effort, but above all cognitive load in daily operations. The operating surface for classic services and containers becomes largely identical.

In addition, a resilient operating contract is created: the desired runtime is described declaratively and can be restored consistently after host-level changes.


Origin and integration into Podman

The idea behind Quadlets comes from consistently using systemd as the operational backbone on Linux servers.

  • Earlier Podman approaches often relied on manually generated systemd units.
  • With Podman 4.4 (2023), Quadlet became officially available as an integrated declarative approach.
  • Since then, it has become established especially where container operations are needed without a full orchestration platform.

Especially in Fedora, RHEL, and compatible distributions, this fits very well with existing systemd-based operating reality.


Role on Red Hat and derivatives

On Red-Hat-centric platforms, the combination of Podman + systemd is a natural fit anyway:

  • systemd is standard
  • Podman is stable and well documented
  • Operating processes are often organized around services

In these environments, Quadlets create a pragmatic middle path:

  • more structure and repeatability than “just podman run
  • significantly less platform overhead than a full Kubernetes stack

For many teams, this is exactly the point where standardization becomes realistic.

And this is exactly where the operational leverage is. Not everyone on the team must master every container option in detail. What matters is that the contract between application and operations is clearly defined and remains reproducible through familiar service mechanisms.

Until then, I had mostly built such hybrid scenarios with Podman tasks in Ansible. That works, but has two clear downsides: no true dependency management at the service layer and a continuous dependency on Ansible for redeployments.

In this context, podman-compose was more of a migration aid or stopgap for Docker emulation. Quadlet, by contrast, standardizes at a clean, native interface between container runtime and init system. That is what makes the approach so pragmatic.


Strengths and practical limits

Area Assessment
Operations Unified control via systemctl/journalctl, which is a strong standard in enterprise environments.
Maintainability Declarative files are easy to version and form a stable operating contract across upgrades.
Scalability Individual services and appliances are represented very well, but complete cluster topologies are not described by Quadlet alone.
Multi-node operation For larger landscapes, Ansible is a good fit to template Quadlets, roll them out consistently, and orchestrate across nodes.
Onboarding Entry stays simple because the operations team primarily needs to handle systemctl and journalctl confidently.
💡 Operational perspective from the field

My focus on Quadlets comes from a very concrete reality: heterogeneous landscapes, hybrid scenarios combining classic enterprise IT and containers, small operations teams, and the need to avoid unnecessary complexity during on-call duty.

In many on-prem scenarios, especially in IoT, automotive, and industrial environments, the main bottleneck is usually not horizontal scaling. Solid availability can often be achieved with physically separated active-active setups, without unnecessary operational noise.

The bigger operational leverage then comes not from adding more layers, but from clear standardization at a few robust interfaces.

In addition, platforms with many nested layers and numerous service dependencies often increase fragility and diagnosis complexity in everyday operations. Kubernetes is just one example of such multi-layer operating models: containers run in pods, pods on nodes, the node as a Linux system in a VM, the VM in an ESX cluster, and that ultimately on bare-metal hardware. This chain is operable, but in incidents it creates longer failure paths and dependencies that are harder to decouple.

This is especially relevant for small on-call teams when stabilization is needed on a Sunday evening under time pressure. Independently of that, where applications already provide mature redundancy and scaling logic themselves (for example Apache Pulsar with broker and bookie redundancy), additional external control loops can oscillate unfavorably.


Practical Quadlet building blocks

Besides .container, three file types are especially useful:

  • .network for dedicated container networks
  • .volume for persistent data
  • .image for clearly defined image provisioning

This gives understandable, reusable building blocks per application.

frontend.network
webdata.volume
nginx.image
web.container

The result is a declarative stack that is operated like classic services.


Thinking further: what about single-node appliances without systemd?

The interesting question comes next: what if the target platform is not Red Hat Linux and does not use systemd?

A typical example is Alpine Linux. I value Alpine for its minimalism, small attack surface, and refreshingly simple architecture. But OpenRC is the standard there.

ℹ️ Alpine Linux in an operations context

Alpine Linux is a lean distribution with a small footprint, musl libc, and BusyBox as its technical foundation. Especially for appliances, edge systems, and clearly scoped on-prem roles, this is often a very suitable base: little ballast, fast updates, and a well controllable runtime environment.

Alpine Linux: alpinelinux.org

So the experiment was: what if, analogous to systemd Quadlets, there were a generator that creates OpenRC init.d scripts from declarative Quadlet files?

That is exactly what this project came from. The core principle stays the same: describe declaratively, run the generator, then manage services through the native init mechanism.

Example flow on Alpine:

quadlet-openrc check
quadlet-openrc lint
quadlet-openrc generate --clean
rc-update add quadlet-network-frontend default
rc-update add quadlet-volume-webdata default
rc-update add quadlet-image-nginx default
rc-update add web default
rc-service web start
rc-service web status

And in operations:

rc-service web restart
rc-status -a
podman logs web
💡 Quadlet for OpenRC

If you want to use the Quadlet approach in OpenRC environments, this generator project is the matching option: quadlet-openrc on GitHub

Note: The current state is experimental code, only partially tested so far, and developed with support from AI agents.


Personal conclusion

When small teams operate hybrid landscapes of classic enterprise software and containers, without Kubernetes being truly necessary, one point is central:

Standardizing at the systemctl and journalctl level is the smallest common denominator that every operations team should target in the short term.

Quadlets are not a theoretical construct for this, but an immediately useful tool. That is exactly why they are so valuable in practice. At the same time, the OpenRC approach shows that this operating model can be extended meaningfully to systems without systemd, with manageable effort.


Image credit: The Docker logo is a trademark of Docker Inc.; used in the context of editorial reporting. Tux, the Linux mascot, was created by Larry Ewing (using GIMP, 1996); used in the context of editorial reporting.