[HN Gopher] Quadlet: Running Podman containers under systemd
___________________________________________________________________
Quadlet: Running Podman containers under systemd
Author : gjvc
Score : 254 points
Date : 2025-03-24 00:27 UTC (22 hours ago)
(HTM) web link (mo8it.com)
(TXT) w3m dump (mo8it.com)
| brirec wrote:
| It's funny to me that this post calls out Podman-Compose as "not
| actively maintained" with its last commit being 5 months ago,
| then turns around to recommend Podlet (whose last commit was...5
| months ago) as an alternative.
|
| Podlet can be useful and helpful, but ultimately it doesn't
| support many of the features of Docker Compose and doesn't always
| provide a clean translation. In particular, Podlet doesn't
| support stacking multiple yaml files (e.g., -f docker-compose.yml
| -f docker-compose.override.yml)
| benatkin wrote:
| Commit date isn't very accurate for showing something is
| maintained, but can show if something is unmaintained. 5 months
| doesn't mean something is unmaintained. Try 2 years. It does
| raise concern though. 5 months absolutely doesn't show
| something is maintained though. There are so many reasons to
| update a repo of something that's unmaintained and only the
| recent and awful IMHO GitHub archive feature prevents this.
| anthropodie wrote:
| To be fair podlet functionalities don't require constant
| updates which is not true in case of podman compose.
|
| Podlet is a helper. In the long run its better to work with
| quadlets.
| goku12 wrote:
| If you're a fan of compose files, then you can use Docker's own
| compose application [1] with Podman [2]. It seems that the
| compose cli controls the engine using its socket. Both podman
| and docker engines have the almost same API. I'm using this
| approach since podman-compose didn't work as expected. Docker-
| compose is usually installed as a plugin for the docker client.
| However, I use it as a standalone application for use with
| Podman. In addition, I prefer using docker 'contexts' instead
| of the DOCKER_HOST environment variable to set up the
| integration.
|
| Also, note that if plain quadlets aren't powerful enough for
| you, quadlets [3] and plain podman [4] also support running a
| limited set of kubernetes manifests.
|
| Added later: I still haven't figured out how podman handles the
| 'restart' option in compose files, since podman doesn't have a
| supervisor daemon. Meanwhile, I know that the 'healthcheck'
| option depends on systemd timers. Automatic health check didn't
| work for me when using Podman on a non-systemd distribution
| (Gentoo). However, I could trigger the health check manually
| and that would lead to the rest of the setup running to
| completion.
|
| [1] https://github.com/docker/compose
|
| [2] https://docs.podman.io/en/latest/markdown/podman-system-
| serv...
|
| [3] https://docs.podman.io/en/latest/markdown/podman-
| systemd.uni...
|
| [4] https://docs.podman.io/en/latest/markdown/podman-kube-
| play.1...
| pydry wrote:
| >In addition, I prefer using docker 'contexts' instead of the
| DOCKER_HOST environment variable to set up the integration.
|
| How on earth is that possible? Docker compose requires a
| daemon and the DOCKER_HOST var fo be set.
|
| I always thought using it defeated the point of podman.
| goku12 wrote:
| > How on earth is that possible? Docker compose requires a
| daemon and the DOCKER_HOST var fo be set.
|
| Docker contexts [1] is an alternative to DOCKER_HOST
| variable. It may have been inspired by kubectl contexts
| (just a speculation). It's more principled than the
| variable, in my opinion.
|
| > I always thought using it defeated the point of podman.
|
| Podman doesn't have a persistent daemon like Docker's that
| monitors the running containers. However, taking inputs
| over a socket is a useful feature in Docker. Podman
| achieves this without a persistent daemon using systemd
| socket units [2]. Whenever a request is received at the
| socket, systemd spins up podman to serve it. Podman keeps
| listening on the socket and then exits after a short period
| of inactivity (like 5s). So it's not quite comparable to
| what Docker does.
|
| [1] https://docs.docker.com/engine/manage-
| resources/contexts/
|
| [2] https://docs.podman.io/en/stable/markdown/podman-
| system-serv...
| bootsmann wrote:
| It doesn't require the daemon afaik, you can set the
| DOCKER_HOST to the podman.sock and it will work more or
| less transparently. Fedora has a podman-docker package that
| configures this.
| stryan wrote:
| Quadlet is one of the best things to have come out of Podman and
| I highly recommend anyone curious about Podman or switch to
| container-based workloads to check them out. Being able to slot
| containers in and treat them like essentially any other system
| service feels great, plus I don't have to learn some extra
| orchestration layer to get them to work together or depend on
| non-container resources. I can just write the same systemd units
| I'm already writing. The auto-updating and service restart/notify
| on failure/etc is just icing on the cake. I've seen the
| equivalent Docker versions before and they're awful; giant messy
| run commands to try to work around the Docker daemon and half the
| time you end up with phantom services and containers anyway.
| Quadlet's end up being much cleaner; plus it means your whole
| setup (besides volume contents) exists with your other systemd
| units (/etc/systemd/, .config/systemd, /usr/local/lib/systemd,
| etc) so it's easy for backups.
|
| The only downside is they're not really an answer to docker-
| compose on the local development side and the podman team doesn't
| seem super interested in tackling that segment. User containers
| are nice for long running local test infra (i.e. a background
| database) but are too clunky for a normal compile-> docker
| compose up -> test -> docker compose down loop. The best answer
| is either .kube Quadlets (kubernetes plays) or using docker
| compose [0] against the podman socket.
|
| Either way, I've enjoyed using quadlets enough that I've spent
| the last few months writing a gitops tool for managing them in my
| spare time. They just feel like the right way of managing
| containerized servers.
|
| [0] NOT podman-compose, which the article points out as being not
| very good and under-developed. Podman implements most of the
| compose spec so you can use docker compose for most situations. I
| suspect many people who tried Podman when RH first started
| pushing it ran into Podman 3 being kinda of bleh and podman-
| compose being awful and bounced off it.
| spockz wrote:
| I wanted to use quadlets and tried podlets as well since I
| wanted to try staying close to the RH paradigm. The experience
| coming from docker compose (on top of podman) was horrendous.
| It became a rabbit hole of trying with different flags,
| upgrading versions, following suggestions from podlet itself to
| switch to another tool, etc.
|
| Ultimately my systemd just executes `podman compose up`.
|
| What are the benefits of quadlets as opposed to letting compose
| do its job?
|
| Update: podman runs under my user, no demon whatsoever.
| lotharcable wrote:
| It integrates naturally into my desktop environment.
|
| I drop a .container file into ~/.config/containers/systemd/
| and the rest is taken care of. I use yadm to manage my dot
| files and that way it ends up on all the systems I want it.
|
| Never tried podlet, though. I just write the container file
| directly.
| stryan wrote:
| Not sure I follow; you don't need to use podlet at all unless
| you're migrating from existing compose files and want some
| help. I don't use it outside of a few one-offs. If you're
| referring to "pods" as in the kubernetes-style container
| orchestration, than you don't have to use those either. Did
| you happen to try this on Ubuntu/Debian? Both distros tend to
| have very old versions of Podman in the repos. TBH podman was
| not worth using before 4.2 or so, no matter what Red Hat
| said. I'm not sure I'm following your situation/ use-case
| though.
|
| If you're already running podman containers as systemd units,
| then the main benefit would probably be better systemd
| integration and without having to write separate compose
| files. If you're fine with the latter than A) you're the only
| person I've met who's happy with podman compose and B) you
| probably won't gain _that much_ from switching to quadlets.
| Out of curiosity, does systemd spinning up podman-compose
| still properly keep the resulting container processes in the
| same cgroup? If not, that would be a decent benefit to
| swapping to quadlets.
| jeppester wrote:
| The trick for development is to enable the podman socket (for
| the user for rootless containers) and then use the standalone
| version of docker-compose.
| arcanemachiner wrote:
| I haven't touched this subject for a couple years now, but I
| remember that this feature was broken for a while after
| Compose was rewritten (in Go?).
|
| Can anyone share their experience with Podman + Docker
| Compose in recent times? It was a really great workflow for
| me at the time.
| jeppester wrote:
| I use it every day, it has been working flawlessly for me
| for ~2 years.
| robohoe wrote:
| Just make sure you're using a relatively new version of
| Podman, v3 had some issues with sockets on Debian and
| CentOS
| sureglymop wrote:
| It works perfectly fine if you install docker but just the
| CLI (e.g. on debian docker provides a package for that in
| their deb repository).
|
| Then you can use docker contexts to make the default
| context your podman socket. Then you just use `docker
| compose` as you normally would. I usually use this with
| rootless podman installs.
| gm678 wrote:
| I've been looking for a better solution for local dev on
| services deployed via quadlet, could you elaborate on this?
|
| I just took a look at the socket activation docs[0]. Is my
| understanding correct that no `compose.yaml` is required,
| just running `docker-compose up` with the appropriate env var
| pointing to the socket is enough to trigger a connection and
| service activation?
|
| [0] https://github.com/containers/podman/blob/main/docs/tutor
| ial...
| jeppester wrote:
| That is exactly what I do.
|
| As far as I remember my podman installations on both fedora
| and ubuntu came with a podman.socket service that I could
| enable as easily as running: `systemctl --user enable --now
| podman.socket`
|
| Then I installed the standalone version of docker-compose:
| https://docs.docker.com/compose/install/standalone/
|
| I don't remember having to do more to get a working
| `docker-compose` command.
| bityard wrote:
| I think I understand that quadlets are containers managed by
| systemd. But I'm still in the dark about why they are called
| that, or why they need a special opaque name.
| goku12 wrote:
| The documentation for quadlets mention this:
|
| > What do you get if you squash a Kubernetes kubelet? A quadlet
|
| The idea is that podman doesn't have a supervisor daemon like
| docker does. Kubelet also performs more or less the same
| function. But podman can leverage the facilities in systemd to
| perform the same function. In a way, quadlets integrate a
| kubelet's functionalities into systemd (rather incompletely).
| That's the reason for the pun involving squashing a cube into a
| quadrilateral (a square actually).
| udev4096 wrote:
| docker compose is way too good to be fiddling around with
| alternatives. Podman is nice but the quadlet solution doesn't
| even come close to what docker compose offers
| goku12 wrote:
| Just for info, you can use Docker's official compose (Go)
| client [1] and podlet [2] (mentioned in the article) with
| podman to run compose files.
|
| [1] https://docs.podman.io/en/latest/markdown/podman-system-
| serv...
|
| [2] https://github.com/containers/podlet
| pdhborges wrote:
| This is using docker-compose. The old deprecated python
| standalone tool. Doctor compose v2 is a plug-in written in go
| for the docker cli.
|
| Edit: looks like Docker release docker-compose v2 as a go
| standalone tool
| (https://docs.docker.com/compose/install/standalone/). I
| stand corrected.
| aprilfoo wrote:
| Can you please elaborate? What docker compose offers that a
| quadlet based deployment cannot match?
| muti wrote:
| I wanted to try something different when I reset my self host set
| up several years ago, and went with openSUSE MicroOS. Ultimately
| it has led to podman containers running under systemd/quadlet and
| I'm quite happy with the current set up.
|
| Containers auto update with built in podman tooling, getting at
| logs and monitoring is through the usual systemd tools. When I
| need to change something, it's easy to work out where the config
| files are if I have forgotten and they are easy to read and
| change. Rootless and daemonless is nice too.
|
| I tried a few things along the way, podman compose felt clunky so
| I'm glad it is deprecated and it's clear quadlets are the way to
| go.
|
| There was a learning curve and there's less information out there
| than with docker, so keep that in mind. I would still lean
| towards docker and docker compose for local dev to bring a stack
| of services up and down.
| stryan wrote:
| The quadlet + MicroOS (or any other Atomic distro i.e. Fedora
| CoreOS) is a very powerful combo; I've been on the slow process
| of migrating all my nodes over to MicroOS and pushing for it or
| something similar at work. The combo of automatic rollbacks for
| base OS and declarative container configs+auto-updates feels
| lock they just slot together.
| jeppester wrote:
| I'm using fedora coreos to run nextcloud on a cheap old
| workstation. It took some work to get the configuration right,
| but I'm very impressed by how little maintenance I need to do
| (so far none at all).
|
| If anyone is interested in doing the same, my configuration can
| be found here for inspiration:
| https://github.com/jeppester/coreos-nextcloud
| mati365 wrote:
| If anyone interested - I made recently Ansible template for
| Quadlet deployment that shows how easy is it.
|
| GH: https://github.com/Mati365/hetzner-podman-bunjs-deploy
| linsomniac wrote:
| Bug report: Your example uses "example.site.org" instead of
| "site.example.org". https://en.wikipedia.org/wiki/Example.com
| cvhc wrote:
| The format is clearer than podman generate systemd or kubernetes
| YAML. And the integration with systemd is great.
|
| What annoys me is Podman upstream doesn't offer a repo for
| Debian/Ubuntu. I was stuck at version 4.3.1 on Debian stable,
| missed many new features and eventually decided to go back to
| Docker compose.
| duckmysick wrote:
| I ran into this problem when I wanted to use quadlets on
| Raspberry Pi running Debian.
|
| The proposed workarounds were compiling Podman yourself or
| using debian/testing.
| alexellisuk wrote:
| Interesting to see Qualet on the front page of Hacker News. I
| don't think it has had enough attention. We had Ygal & Valentin
| from the project submit a guest post on how to run an inlets
| tunnel client (think of Ngrok/Cloudflared, but self-hosted
| without any SaaS limits) -
| https://inlets.dev/blog/2023/10/03/client-quadlet.html
|
| Rather than using [container] they used [kube] and were able to
| bring along standard Kubernetes YAML making it quite portable.
| eulenteufel wrote:
| I really like quadlets as they enable using containers like
| normal system services. That said the UX for rootless containers
| does not play well with this conceptualization.
|
| Normally system services run as system users in the _system_
| systemd-session, but for rootless containers the services reside
| in the _user_ systemd sessions of the system user. I 'd love to
| be able to run rootless quadlets within the system session.
| GCUMstlyHarmls wrote:
| Is there any effective difference by enabling user-linger and
| running rootless via user systemd? That's what I've always
| done.
| Svenstaro wrote:
| I used to do that but I find the UX of that quite annoying
| because before you can do: systemctl status and see what's up
| with all the system services. Now you have to do systemctl
| status -M <user-for-that-stack> for every stack that you're
| running to get a complete picture.
|
| I haven't found a way around that and would be very thankful
| for pointers.
| aprilfoo wrote:
| I'm happily using quadlets as a lightweight container
| orchestration tool for few months now and i also think it
| deserves more attention. RH is doing a great integration job
| pushing the systemd ecosystem.
|
| As many projects still only mention docker/compose, it would be
| great to have a community maintained quadlet store - something
| like https://github.com/dwedia/podmanQuadlets?
| sunshine-o wrote:
| I have been trying to adopt Quadlet since before Covid if I
| remember correctly (it wasn't named Quadlet yet) because this is
| such a key piece of the puzzle.
|
| I kept using things like Docker Compose for simple services until
| now but it always felt like a temporary solution.
|
| So I try every year and every time I am not convince this thing
| is solid/polished enough yet. I am confident 2025 is gonna be a
| go according to the positive comments here.
|
| My sincere question is: why did it took about 10 years to have a
| basic working integration between the service manager and
| containers (and by containers I mean the way we run most non
| system services nowadays)?
|
| My intuition is there must be some ugly politics involved between
| IBM/Redhat, Systemd and some other actors but I can't figure it
| out....
| eriksjolund wrote:
| Socket activation can be used with quadlets but not with docker-
| compose. That is a big advantage.
|
| https://github.com/containers/podman/blob/main/docs/tutorial...
| l11r wrote:
| I recently discovered them and made an entire homelab based on
| the atomic OS and rootless Quadlets, can highly recommend them.
| They also allow to use systemd socket activation. Which means you
| can create systemd http/https sockets for example and activate
| Traefik automatically just like ssh.socket and podman.socket
| activates sshd.service and podman.service accordingly. It's a
| lifesaver since this is basically the only way to preserve source
| IP in rootless setups (rootless Podman/Docker usually doesn't
| easily allow to preserve source IP without major drawbacks).
|
| https://github.com/savely-krasovsky/homelab
| robertlagrant wrote:
| Nice. How long does it take for Traefik to activate?
| l11r wrote:
| It's few seconds usually. Traefik is not a bottleneck after
| system start, most time takes containers startup.
| robertlagrant wrote:
| Thanks!
| smjburton wrote:
| > ... the old method was too hacky and involved the usage of
| redundant commands.
|
| > There must be an easier way, you might think. Especially if you
| experienced the convenience that Docker Compose provides.
|
| I really hope this new approach helps people migrate from Docker
| to Podman. Docker-Compose is the reason a lot of people resist
| switching (including myself), and admittedly, Podman didn't
| really have an answer until Quadlets. If you were hesitant about
| migrating from Docker because of Docker-Compose, Podman with
| Quadlets is a much more comparable alternative. You probably
| won't miss Docker as much as you think, and you'll benefit from
| enhanced security running rootless containers.
| nine_k wrote:
| Not going to switch until I'm able to have several independent
| Quadlet environments, not "put everything in
| ~/.config/quadlet/systemd". This is essential for development
| and testing. For now, quadlets are strictly a deployment
| solution.
| bogwog wrote:
| I use these all the time and I LOVE them! They simplify such a
| tedious and annoying process, and it makes Docker compose (and
| Docker in general) look obsolete. It's definitely worth the
| effort to learn them.
|
| The only issue is that they're not widespread yet, so often I
| have to spend the time to port a Dockerfile to a set of quadlet
| files. I've gotten fairly proficient at it by now, but I can see
| why most people would rather use podman compose instead.
| robertlagrant wrote:
| We ship a preinstalled device that uses systemd. I would love to
| use containerisation to isolate different software dependencies.
| Is it possible to ship a podman container in a package install,
| e.g. a .deb?
| lukaslalinsky wrote:
| It would be just a super simple package with one config file
| for the container, dependency on podman, and maybe a post-
| install script for creating system account and directories for
| data. I haven't done this myself for containers, but I don't
| see any reasons why it wouldn't work.
| lukaslalinsky wrote:
| I've been using this method on a few servers where I don't want
| to run Kubernetes and I really like it. It feels like native
| support for docker-like containers in Linux, instead of a foreign
| concept that needs it's own management/logging. This is the
| killer feature of Podman, it doesn't make sense for me to use
| Docker in prod.
| vbezhenar wrote:
| Native support would be systemd-nspawn running containers
| without podman, because systemd already have everything needed
| to run containers.
| psadauskas wrote:
| Quadlet is a nice alternative for use-case of docker compose to
| "run all these interdependent containers in a production-like
| environment". I wish it (or something) was better about the other
| use-case of docker compose: development. docker compose will
| bring up the db, redis, opensearch, and other random
| dependencies, an nginx proxy, and a dev container with `.:/app`
| mounted as a volume. You can bring up all those containers
| together, destroy them together, check in the docker-compose.yml
| file, etc...
|
| Quadlet wants me to have all the files in
| `~/.config/containers/systemd`, so they're really not isolated to
| the project any more, and not in a convenient place to be checked
| in and shared with other devs (who also have to be using podman).
| Most still use docker, its what's availabile on codespaces and
| other hosted dev envs.
|
| So we use docker compose, with a checked-in yaml file. I use
| podman, so I have to manually add `:Z` to all the volumes, but
| regular docker chokes on that. I wouldn't mind having an
| alternative to docker compose for development, but Quadlet
| doesn't seem like a good fit.
| deno wrote:
| You can use `podman-compose --in-pod=1 systemd -a create-unit`
| and it will create podman-compose@ service, then you can
| register compose.yml files with `podman-compose systemd -a
| register` with a $name, after that you can manage those pods
| based on compose files using podman-compose@$name.service.
| Works completely rootless too.
| sc68cal wrote:
| A podman pod is what you are looking for, in that case, and I
| would orchestrate all that via Ansible, and distribute the
| Ansible playbooks to everyone else so they can run it locally.
| ptsneves wrote:
| systemd-run allows you to run transient systemd services based
| on arbitrary commands. It will create nice transient units and
| if needed timers all with systemd scope rules. See [1]
|
| [1] https://www.freedesktop.org/software/systemd/man/systemd-
| run...
| kccqzy wrote:
| Huh TIL this is called a quadlet. It turns out I already wrote
| several files in ~/.config/containers/systemd following some
| other tutorial online and didn't know this is called a quadlet.
| geenat wrote:
| Big fan of the unification of systemd and podman.
|
| > https://mo8it.com/blog/quadlet/#too-many-files
|
| IMHO bad take- give people an option to consolidate
| build/orchestration into 1 file without relying on an external
| image repository (... like the author is doing with docker.io...
| ugh).
|
| Being "all in one" makes docker-compose still competitive. In the
| year 2025, quadlet makes top-level project directories very busy.
|
| Could be OK if all the files ended up in a sub-directory but
| systemd highly restricts usage of ".." traversal; so there's an
| explosion of files at the top level of your project.
| perrygeo wrote:
| I was an early adopter of Docker (because Python) and I
| immediately hit the "now how do I run it in prod?" question. K8s
| quickly jumped in to fill that space. But I like to imagine a
| saner world where Quadlet came first and became the standard.
| anonfordays wrote:
| HashiCorp Nomad is a great alternative to this that scales to
| thousands of nodes. It's super lightweight and supports Podman
| directly.
| jcgl wrote:
| Unfortunately, it's not free and open source anymore.
| anonfordays wrote:
| Thank you for altering me. I just read that it also moved to
| BUSL. I thought only Terraform did so, not the entire
| HashiCorp portfolio.
___________________________________________________________________
(page generated 2025-03-24 23:01 UTC)