[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)