Managing Containers with Podman Quadlets in RHEL 10
Objective
This guide explains how to manage Podman containers using Quadlets in Red Hat Enterprise Linux 10. By the end, you will know how to:
- Install and verify Podman on a RHEL system
- Create and manage Quadlet
.container,.volume, and.networkfiles - Pull container images and run them as systemd-managed services
- Configure persistent storage and custom networks for containers
- Reload systemd, start, stop, inspect, and verify running containers
- Understand how this connects to RHCSA exam objectives for container management
Containers are now a core part of enterprise Linux administration. The older approach of managing containers outside of systemd, using standalone podman run commands or manually written service files, works but doesn't scale cleanly. Quadlets change that by letting you define containers, volumes, and networks in lightweight configuration files that systemd reads and converts into service units automatically. The result is containers that behave like native Linux services, with the same start, stop, enable, and status commands you already know.
What Are Podman Quadlets
A Quadlet is a configuration file that describes a container, a volume, or a network. systemd reads these files through a generator and produces the equivalent .service unit behind the scenes. You never write the service file directly. You write the simpler, more readable Quadlet file instead, and systemd handles the translation every time it reloads.
| File Type | Extension | What It Defines | systemd Unit Generated |
|---|---|---|---|
| Container | .container |
The container image, ports, volumes, environment, and options | name.service |
| Volume | .volume |
A named Podman volume for persistent storage | name-volume.service |
| Network | .network |
A custom Podman network with defined subnet and gateway | name-network.service |
Quadlets are placed in one of two locations depending on whether you are running them as root or as a regular user:
- System-wide (root):
/etc/containers/systemd/ - Per-user (rootless):
~/.config/containers/systemd/
Quadlets vs Traditional Approaches
| Approach | How It Works | Advantages | Disadvantages |
|---|---|---|---|
| podman run | Start containers manually from the command line | Simple, immediate | Containers don't survive reboots, no systemd integration |
| podman generate systemd | Generate a .service file from a running container, copy it to systemd |
Containers start at boot | Generated files are complex, brittle, deprecated in RHEL 10 |
| Quadlets | Write a .container file, systemd generates the service unit automatically |
Clean syntax, auto-generates on reload, native systemd integration, recommended in RHEL 10 | Requires understanding Quadlet file format |
Red Hat has deprecated podman generate systemd in RHEL 10. Quadlets are now the recommended and supported approach. For RHCSA exam preparation on RHEL 10, this is the method you need to know.
Step 1: Install and Verify Podman
# Install Podman
yum install podman -y
# Verify the installation
podman --version
# Confirm the Quadlet generator is available
ls /usr/lib/systemd/system-generators/ | grep podman
The Quadlet generator (podman-system-generator) is included with Podman on RHEL 10. If it is present, systemd will automatically process .container, .volume, and .network files from the correct directories on every daemon reload.
Step 2: Pull a Container Image
# Pull the Apache HTTPD image from Docker Hub
podman pull docker.io/library/httpd
# Verify the image is available locally
podman images
# Inspect the image before deploying it
podman inspect docker.io/library/httpd | grep -i exposed
Step 3: Create a Quadlet Volume
Create persistent storage for your container before defining the container itself. The volume file goes in the Quadlet directory and becomes a managed systemd unit that the container depends on.
# Create the Quadlet directory if it doesn't exist
mkdir -p /etc/containers/systemd/
# Create a volume Quadlet file
cat > /etc/containers/systemd/webdata.volume << EOF
[Volume]
Label=app=webserver
EOF
This creates a named Podman volume called webdata. The name is derived from the filename: webdata.volume creates the volume webdata. You reference it by this name inside the container file.
Step 4: Create a Quadlet Network
# Create a custom network Quadlet file
cat > /etc/containers/systemd/webnet.network << EOF
[Network]
Subnet=192.168.100.0/24
Gateway=192.168.100.1
Label=app=webserver
EOF
This defines a custom network called webnet (again, derived from the filename). Containers connected to this network can communicate with each other by container name, and the network is managed as a systemd dependency of anything that uses it.
Step 5: Create the Container Quadlet File
Now define the container itself. This is the core Quadlet file that ties the image, volume, network, and service behaviour together.
# Create the container Quadlet file
cat > /etc/containers/systemd/myhttpd.container << EOF
[Unit]
Description=Apache HTTPD Container
After=network-online.target
[Container]
Image=docker.io/library/httpd
PublishPort=8080:80
Volume=webdata.volume:/usr/local/apache2/htdocs
Network=webnet.network
Environment=APACHE_LOG_DIR=/var/log/apache2
[Service]
Restart=always
TimeoutStartSec=60
[Install]
WantedBy=multi-user.target
EOF
Breaking down the key sections:
- [Unit]: standard systemd unit directives, same as any service file
After=network-online.targetensures the container starts only after networking is available
- [Container]: the Quadlet-specific section where you define container behaviour
Image=: the full image reference including registryPublishPort=: maps host port 8080 to container port 80, same as-pinpodman runVolume=: mounts thewebdatavolume, referenced by the Quadlet volume nameNetwork=: connects to thewebnetnetwork, referenced by the Quadlet network nameEnvironment=: sets environment variables inside the container
- [Service]: standard systemd service directives that control restart behaviour
- [Install]: defines when this service is enabled, same as any systemd unit
Step 6: Reload systemd and Start the Service
# Reload systemd so it processes the new Quadlet files
systemctl daemon-reload
# Verify the generated service unit is visible
systemctl list-unit-files | grep myhttpd
# Start the container service
systemctl start myhttpd.service
# Enable it to start automatically at boot
systemctl enable myhttpd.service
# Check the service status
systemctl status myhttpd.service
After daemon-reload, systemd reads the Quadlet files and generates the corresponding service units. The container now appears and behaves as a normal systemd service. You manage it with the same commands you use for any other service.
Step 7: Verify the Running Container
# Confirm the container is running
podman ps
# Check container details including port mappings
podman ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# Test the web server is responding on the published port
curl http://localhost:8080
# View container logs
podman logs myhttpd
# Check which Podman volumes exist
podman volume ls
# Check which Podman networks exist
podman network ls
# Inspect the container for detailed configuration
podman inspect myhttpd
Managing the Container Service
Because the container is now a systemd service, every management action uses standard systemctl commands. There is nothing container-specific about how you operate it day to day.
| Task | Command |
|---|---|
| Start the container | systemctl start myhttpd.service |
| Stop the container | systemctl stop myhttpd.service |
| Restart the container | systemctl restart myhttpd.service |
| Check container status | systemctl status myhttpd.service |
| Enable at boot | systemctl enable myhttpd.service |
| Disable at boot | systemctl disable myhttpd.service |
| View service logs | journalctl -u myhttpd.service |
| Reload after editing Quadlet file | systemctl daemon-reload then systemctl restart myhttpd.service |
Common Mistakes
- Forgetting
systemctl daemon-reloadafter editing a Quadlet file. Quadlet files are not service units. systemd needs to regenerate the actual service unit from the updated file before your changes take effect.- Always run
daemon-reloadafter any change to a.container,.volume, or.networkfile
- Always run
- Referencing volumes or networks by the wrong name. The name used in the
Volume=orNetwork=directive must match the Quadlet filename exactly (without the extension).webdata.volumecreates a volume namedwebdata, referenced aswebdata.volumeinside the container file
- Placing files in the wrong directory. System-wide Quadlets go in
/etc/containers/systemd/. Per-user rootless Quadlets go in~/.config/containers/systemd/. A file in the wrong location is silently ignored.- For rootless services, also remember to enable lingering:
loginctl enable-linger username
- For rootless services, also remember to enable lingering:
- Trying to hand-edit the generated service unit. The
.servicefile systemd generates from a Quadlet is regenerated on everydaemon-reload. Any manual edits to it are overwritten. Always edit the source.containerfile instead. - Not enabling the service after starting it.
systemctl startruns the container now.systemctl enablemakes it start at boot. On the RHCSA exam, configurations must survive a reboot to score points. Both commands are required.
Quadlets and the RHCSA Exam
Container management is an explicit objective on the RHCSA exam for RHEL 10. The exam expects you to configure a container to start automatically as a systemd service, and Quadlets are the supported method for doing this on RHEL 10 now that podman generate systemd has been deprecated.
What the exam tests in this area:
- Running a container from a specified image
- Configuring the container as a service that starts at boot
- Persistent storage: attaching a volume so data survives container restarts
- The configuration must survive a reboot and be verified after one
The same pattern applies here as everywhere else on the RHCSA: using systemctl start without systemctl enable is a partial answer that scores zero. Test every container configuration by rebooting your practice environment and confirming the service comes back up automatically.
Practice tip: Set up the same scenario twice. Once using the older
podman generate systemdapproach so you understand where it came from, and once using Quadlets so you know the current method. The comparison makes both approaches easier to remember.
Practice This in a Real RHEL Environment
Reading about Quadlets is useful. Typing the commands on a real RHEL 10 system where you can see what happens when you get something wrong is how the knowledge actually sticks. The Quadlet file format is easy to misread until you have run daemon-reload a few times and diagnosed why a service didn't appear. LinuxCert.Guru has a dedicated hands-on lab for exactly this topic: Manage Containers with Quadlets. It covers container deployment, volume configuration, network setup, and service automation on a live RHEL environment with auto-graded tasks that verify your configuration is correct, including the reboot check.
Conclusion
Podman Quadlets are the current standard for container management in RHEL 10, and they are the approach the RHCSA exam expects you to know. The key ideas to take away:
- Quadlets use
.container,.volume, and.networkfiles that systemd converts into service units automatically on eachdaemon-reload - System-wide Quadlets go in
/etc/containers/systemd/, rootless Quadlets in~/.config/containers/systemd/ - Once deployed, containers behave as native systemd services and are managed with the same
systemctlcommands you already know - Always run
systemctl daemon-reloadafter editing any Quadlet file - Always run both
systemctl startandsystemctl enable: start runs it now, enable makes it survive reboots podman generate systemdis deprecated in RHEL 10: learn Quadlets, not the older method
The Quadlet file format is small and readable. Once you have written one container file, volume file, and network file and seen how systemd picks them up, the whole model becomes clear. That clarity comes from doing it, not from reading about it.
Start the Manage Containers with Quadlets lab at LinuxCert.Guru → https://linuxcert.guru/?name=rh134-manage-containers-quadlets