A repository where I store my podman quadlets.
All quadlets in this repo are rootless.
The main repository now resides in Codeberg, the Github repository is now a mirror. Issues can be reported in either.
This repository is rather opinionated:
- Only the
latest
tag is used, unless it's not possible to do so- It's a moving target, so this repository is never outdated
- An up-to-date service is a service with all patches and CVEs covered ASAP
- It allows for auto-updates with default fallbacks
- The quadlets are designed for rootless podman, not rootful podman
- The directory structure is like this so you can simply copy the folder of the project you want to ~/.config/containers/systemd
- Podman supports an extra directory level in ~/.config/containers/systemd
All quadlets available here are expected to follow this behavior:
- If the container file contains "generate", "build", or "init" in its name, it's not supposed to restart
- All other container files are supposed to start on boot (default.target)
- If a service has dependencies, those dependencies should automatically start before the main service (WantedBy)
- If a service has dependencies, when the service crashes or stops, all its dependencies should stop (BindsTo)
- All quadlets are supposed to force log to systemd even if you have set it up to not do that (LogDriver)
Quadlets are a new way to manage containers. They consist of .container
files.
They were originally a separate project which has now been merged into Podman.
By writing an INI file with the .container
extension (as well as .network
,
.volume
and .kube
if needed) and storing it in a certain directory,
systemd is able to automatically generate a systemd
service using
systemd-generate.
Once the service is started, it will pull all required images and run a podman
container.
It deprecates, but is not a direct alternative to,
podman-generate-systemd.
It is more of an alternative to docker-compose.yml
or compose.yml
files.
So instead of writing compose files following the
Compose Specification,
and instead of using something like
docker compose or
podman compose,
you write files in INI format, similarly to a systemd unit.
It is not a direct alternative to podman-generate-systemd because it does not
generate the new format using your existing compose files. You need to manually
create new files based on them. Thankfully, there is a tool called
Podlet that is able to generate
container files for you based on podman run
, podman compose
or a
{docker-}compose.yml
.
Podman unit search path:
- /etc/containers/systemd/
- /usr/share/containers/systemd/
Podman user unit search path:
- ~/.config/containers/systemd/ <---- Only for your user
- /etc/containers/systemd/users/$(UID) <---- Only for a specific user
- /etc/containers/systemd/users/ <---- For all users
If you have no idea how to get started or you are using rootless Podman, store your container files in ~/.config/containers/systemd/ and run them as a user.
This quickstart assumes you will be using rootless containers. If you want to use rootful podman quadlets, change the images and configurations accordingly, as those might vary according to each upstream project.
- Create the folder
~/.config/containers/systemd/
. - Copy the
owncast/
folder to~/.config/containers/systemd/
. - Run
systemctl daemon-reload --user
. - Run
systemctl start --user owncast
.
Done, you now have your own selfhosted Owncast
instance! You can visit it under localhost:8080
and configure it under
localhost:8080/admin
.
Additionally, the following commands might be useful to you:
systemctl status --user owncast
: check the Owncast service status.systemctl list-unit-files --user --all --state generated
: list all generated services.journalctl --user-unit owncast
: see the logs for your Owncast container.podman stats owncast
: monitor the status of your Owncast container.journalctl enable-linger youruser
: let systemd services run while your user is not logged in.
- Podman 4.4.0 or greater
- Crun
- Have CGroupsV2 enabled
- systemd-container
- https://blogs.gnome.org/alexl/2021/10/12/quadlet-an-easier-way-to-run-system-containers/
- https://www.redhat.com/sysadmin/quadlet-podman
- https://www.redhat.com/sysadmin/multi-container-application-podman-quadlet
- https://www.linkedin.com/pulse/quadlets-how-i-learned-stop-worrying-love-dot-adam-clater
- https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html
The real source-of-truth documentation is podman-systemd.unit. You might also want to look at systemd.unit and systemd.service to learn more about how to manage systemd services.
-
The current documentation is scarce, and the only true documentation is a manpage, namely podman-systemd.unit, which is far from ideal. There is the docs folder of the original project, and while useful, it is severely outdated.
-
If your podman container setup relies on Kubernetes Pods / Podman Pods instead of Docker Networks, you are either forced to write your own Kubernetes Deployment files, generate Kubernetes Deployment files with podman-kube-generate, or rewrite your setup to use Docker Networks instead (the easiest option).
-
Depending on your Podman version, not all entries in
podman-systemd.unit
might be supported. In that case, use the respective Podman command line flags under the entryPodmanArgs=
. -
Unlike compose files which have built-in dependency management, this is not present within the
[Container]
section of container files, and together with certain policies, such asRestart=
or modifications to the container command likeExec=
, such features will have to be adapted to systemd unit style. You might want to use WantedBy=default.target in the[Install]
section to start a service on boot. The following is a good read on how unit dependencies behave in systemd: Difference between PartOf and BindsTo in a systemd unit.
-
Podman Pods require you to define ports and whatnot at Pod creation time, which can be unpractical if you need to change your setup in the future. With Quadlets, you alter the container file, reload the daemon and restart the service.
-
Using podman-generate-systemd always generates complex and hard-to-read systemd service files. Quadlets do not have this issue.
-
Using podman-generate-systemd together with podman-compose is not very robust: after making drastic changes to a compose file and recreating the containers/ pods, the generated services will lose their ability to manage those containers. With Quadlets, container files have an inherent connection to their respective systemd services.
-
Extending a service is as simple as adding or removing a few lines and restarting the daemon and service.
-
Systemd features are available to container files. Things like
OnFailure=
to trigger another service if the current one fails,ExecStopPost=
to run an arbitrary command if the current service fails, container logs are stored in journald and are accessible via journalctl, containers can be managed together with systemd timers, etc. This allows for capabilities that are not possible or are difficult to do with compose files. -
Because all processes related to the container are under the same service cgroup, systemd is able to manage it entirely, and changing the respective cgroup affects the entire container.
-
Because the containers are internally run with podman, you can still manage them with podman as you wish. This is useful, for instance, if the container requires a restart after some internal modification to the container (like MediaWiki), or if it needs changes to its matching database (like WriteFreely).