A repository where I store my podman quadlets.
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:
Podman user unit search path:
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.
~/.config/containers/systemd/
.owncast.container
file to ~/.config/containers/systemd/
.systemctl daemon-reload --user
.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.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 entry PodmanArgs=
.
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 as Restart=
or modifications to the container command
like Exec=
, 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).