Additionally, podman has nice systemd integration for such kube services, you just need to write a short systemd config snippet and then you can manage the kube service just like any other systemd service.
Altogether a very nice combination for deploying containerized services if you don't want to go the whole hog to something like Kubernetes.
Last I tried using the .kube files I ran into issues with specifying container networks (https://github.com/containers/podman/issues/12965).
This is sort of "fixed" by using a Quadlet ".kube" but IMO that's a pretty weak solution and removes the "here's your compose file, run it" aspect.
Recently (now that Deb13 is out with Podman 5) I have started transitioning to Podmans Quadlet files which have been quite smooth so far. As you say, its great to run things without all the overhead of kubernetes.
I agree about quadlets, amazing.
Docker has one of the most severe cases of not-invented-here. All solutions require a combination of a new DSL, a new protocol, a new encryption scheme, a new daemon, or any combination there-of. People are sleeping on using buildah directly; which OP alluded to with Bakah (but fell short of just using it directly).
Ever wish you could run multiple commands in a single layer? Buildah lets you do that. Ever wish you could loop or some other branching in a dockerfile? Buildah lets you do that. Why? Because they didn't invent something new, and so the equivalent of a dockerfile in buildah is just a script in whatever scripting language you want (probably sh, though).
This will probably give you the general idea: https://www.mankier.com/1/buildah-from
I came across this when struggling and repeatedly failing to get multi-arch containers built in Circle CI a few gears ago. You don't have access to an arm64 docker context on their x86 machines, so you are forced to orchestrate that manually (unless your arm64 build is fast enough under qemu). Things begin to rapidly fall apart once you are off of the blessed Docker happy path because of their NIH obsession. That's when I discovered buildah and it made the whole thing a cinch.
Claude recently hallucinated this for me:
[Container]
ComposeService=my-service
Yaml=/path/to/your/podman-compose.yaml
For a brief moment in time I was happy but then:Can you really use "ComposeService" in the systemd unit file? I can't find any reference to it
You're absolutely right to question that - I made an error. There is no ComposeService directive in systemd or Quadlet.
It would be a nice best of both worlds...
A irrational part of deployment, meant to trigger corner cases and improve the product's stability.
Today, people who out-source thinking to a LLM get the chaos monkey for free.
The only problem seems to be that the LLM proponents are ahistoricists.
1: https://en.wikipedia.org/wiki/Chaos_engineering#Chaos_Monkey
It is very stupid and is usually wrong in some meaningful way, but it can help break logjams in my thinking. Giving me clues that might be missing. Sort of like how writing gibberish is sometimes effective for writers to break writer's block.
It is also nice for generating boiler plate code for languages that I am not super familiar with.
The biggest problems I have with current state of the art LLMs is that errors compound. Meaning that I only really get somewhat useful answers when starting out with the first few questions or the first couple times I ask it to review some code. The longer the session lasts the more la-la land answers I get.
It is a game of odds. I expect that with systemd and quadlets it is going to particularly useless because there just isn't that many examples out there. It can only regurgitate what it is trained with so if something isn't widely used and checked into code bases it is trained on then it can't really do anything with it.
Which is why it is nice for a lot of common coding tasks, because a lot of code is just same thing tens of thousands people did before for only slightly different contexts and is mostly boilerplate.
Just FYI, `podman generate systemd --files --name mypod` will create all the systemd service files for you.
https://docs.podman.io/en/latest/markdown/podman-generate-sy...
Quadlets now make it much easier to create the units by hand, and ‘ `podman generate systemd` is deprecated.
It was introduced in Podman 4.4 which is circa 2023.
And it takes a while for podman to get up to date in non-Redhat related distributions. Like Debian Stable was stuck on 4.3 until Trixie release this month.
So unless you are using Fedora and friends or something like Arch it is kinda hard time going for podman users. Which is unfortunate.
Docker has a bit of a advantage here because they encourage you to use their packages, not the distribution's.
Here is a example Quadlet configuration i use for syncthing that I run out of my home:
[Unit]
Description=syncthing
After=default.target
[Container]
ContainerName=syncthing
Image=docker://docker.io/syncthing/syncthing:latest
Volume=/home/lothar/.syncthing:/var/syncthing:z
Volume=/home/lothar:/var/home/:rslave
Network=host
Pull=always
Environment=PUID=1000
Environment=PGID=1000
Environment=STGUIADDRESS=''
UserNS=keep-id:uid=1000,gid=1000
SecurityLabelDisable=true
[Install]
WantedBy=multi-user.target default.target
This then gets dropped into ~/.config/containers/systemd/syncthing.containerAnd it is handled automatically.
This configures the syncthing container to always get updated on each startup, bypasses the "rootless" networking by using host networking (rootless networking is limited and slow), and the default Sync dir ends up in ~/.syncthing where as I can add more sync'd directories to my real home directory by directing it to /var/home/ in the syncthing web ui.
As you can see the arguments under "container" is just really capitalized versions of docker/podman arguments.
Also if you like GUIs the podman desktop has support for helping to generating quadlets. Although I haven't tried it out yet.
Incus is an LXD fork, and focuses on "system" containers. You basically get a full distro, complete with systemd, sshd, etc. etc. so it is easy to replace a VM with one of these.
podman and docker are focused on OCI containers which typically run a single application (think webserver, database, etc).
I actually use them together. My host machine runs both docker and incus. Docker runs my home server utilities (syncthing, vaultwarden, etc) and Incus runs a system container with my development environment in it. I have nested c-groups enabled so that incus container actually runs another copy of docker _within itself_ for all my development needs (redis, postgres, etc).
What's nice about this is that the development environment can easily be backed up, or completely nuked without affecting my host. I use VS Code remote SSH to develop in it.
The host typically uses < 10GB RAM with all this stuff running.. about half what it did when I was using KVM instead of Incus.
Within the incus dev environment container though I'm pretty sure I want to keep docker, as I have a lot of tooling that expects it for better or worse (docker compose especially). It also doesn't appear incus integrates buildkit etc. so even if I used it here, I'd still need something else to _build_ OCI images.
That is going to be slower and limited compared to rootful solutions like incus. The easy work around is to use 'host' networking.
If you are using rootful podman then normal Linux network stack gets used.
Otherwise they are all going to execute at native speed since they all use the same Linux facilities for creating containers.
Note that from Podman 5.3 (Nov 24) and newer they switched to "pasta" networking for rootless containers. Which is a lot better, performance wise.
edit:
There are various other tricks you can use for improving podman "rootless" networking, like using systemd socket activation. This way if you want to host services this way you can setup a reverse proxy and such things that runs at native speeds.
How would you configure a cluster? I’m trying to explore lightweight alternatives to kubernetes, such as docker swarm, but I think that the options are limited if you must support clusters with equivalent of pods and services at least.
Right now I'm running,
- podman, with quadlet to orchestrate both single containers and `pods` using their k8s-compatible yaml definition
- systemd for other services - you can control and harden services via systemd pretty well (see https://news.ycombinator.com/item?id=44937550 from the other day). I prefer using systemd directly for Java services over containers, seems to work better imo
- Pyinfra (https://pyinfra.com/) to manage and provision the VMs and services
- Fedora CoreOS as an immutable base OS with regular automatic updates
All seems to be working really well.
Yes. Though unless you have a very dynamic environment maybe statically assigning containers to hosts isn't an insurmountable burden?
So, unless you have a service that requires a fixed number of running instances that is not the same count as the number of servers, I would argue that maybe you don't need Kubernetes.
For example, I built up a Django web application and a set of Celery workers, and just have the same pod running on 8 servers, and I just use an Ansible playbook that creates the podman pod and runs the containers in the pod.
My setup is a bit clunky (having a Hetzner cloud instance as controller and a local server as a node throught Tailscale), from which I get an occasional strange error that k3s pods fail to resolve another pod's domain without me having to re-create the DNS resolver system pod, and that I so far failed at getting Velero backups to work with k3s's local storage providers, but otherwise it is pretty decent.
YMMV
Contrast:
ansible -i server1,server2,server3 deploy_fake_pods.yaml
ssh server1 sudo shutdown -h now
# aww, too bad, now your pods on server1 are no longer
With kubectl apply -f deployment.yaml
for i in $(kubectl get nodes -o jsonpath='{.status.hostIP}'); do
ssh $i sudo shutdown -h now
sleep 120
done
# nothing has changed except you have fresh Nodes
If you don't happen to have a cluster autoscaler available, feel free to replace the for loop with |head -1 or a break, but I mean to point out that the overall health and availability of the system is managed by kubernetes, but ansible is not thatmicrok8s seems exceedingly simple to setup and use. k3s is easy as well.
The straw that broke the camels back was a bug in `podman compose` that funnily enough was fixed two hours ago[1]; if `service1` has a `depends_on` on `service2`, bringing down `service1` will unconditionally bring down `service2`, even if other services also depend on it. So if two separate services depend on a database, killing one of them will kill the database too.
Another incompatibility with Docker I experienced was raised in 2020 and fixed a few months ago[2]; you couldn't pass URLs to `build:` to automatically pull and build images. The patch for this turned out to be a few lines long.
I'm sure Podman will be great once all of these bugs are ironed out, but for me, it's not quite there yet.
[1]: https://github.com/containers/podman-compose/pull/1283
[2]: https://github.com/containers/podman-compose/issues/127
I recommend starting with .container files instead of .kube, unless you're already familiar with kubernetes.
Not sure I'm sold.
> manually create the network
There's no way for me to know what your requirements are, but often times if you just need your containers to talk to each other, all you need is an empty file with a unique name. So `touch MyDVRNetwork.network` to create it, and add `Network=MyDVRNetwork` to your containerfiles.
> and have to stop and start all of the services individually.
Nope, container files are essentially already systemd service files. If you add them to the correct folder and set up the dependencies, systemd will automatically start them in the correct order at boot time, restart them if they fail, etc. That's the best part of quadlet IMO. Literally set it and forget it, and the process works the same for rootless containers (you just need to add them to your user folder instead of the system-wide folder)
It gets even more awesome when you combine them with something like Fedora CoreOS and Butane. With a few small text files, you can declaratively generate an OS image with all of your desired services ready to go. It is pure bliss.
I read about the recently released CLI support for quadlets [0] and the ability to install Quadlets from a URL but still cannot wrap my head around it (as in, no matter how I look at it, Quadlets seem to require non-trivially higher knowledge to use and more steps/files).
If we need a concrete example to discuss: https://github.com/oslc-op/refimpl/blob/main/src/docker-comp...
[0]: https://blog.podman.io/2025/08/level-up-your-container-game-...
But Quadlet needs a container image before it can create a container. The example compose file you linked includes steps for building Dockerfiles. Quadlet doesn't do that. Instead, you'll need to do it as a separate step using buildah (https://www.redhat.com/en/topics/containers/what-is-buildah)
Compose does a lot of stuff, so migrating away from it isn't always easy. In this case, you'd probably need to bring in a build system like Make or some custom scripts to build all the container images you need. Once you rebuild an image, you can restart your quadlet-managed containers with `systemctl restart my-container` and they'll automatically use the new image.
I don't do much web development these days, so I'm definitely not an authority on container-based development workflows. Maybe there are better tools out there, or maybe compose is still the best tool for that job. But quadlets are definitely the better choice when it comes to deploying/orchestrating your containers without getting into a full blown kubernetes setup.
Can i do that with quadlets?
> No copying files to ~/.config/systemd just run docker-compose to start and stop.
Naively, I'd say to create symlinks instead of copying, and run `systemctl daemon-reload`/`systemctl restart ...`. Although there are probably more streamlined web development options out there.
Maybe look into Podman Pods. They're probably closer to what you're looking for, but idk what kind of dev tools exist out there for it. Maybe a few custom shell scripts to run the pod management commands is all you really need?
I did mean symlinks too. The rest of my system shouldn't have to know or care about my project at all.
I just wanna be able to systemctl --user start ./my-service.service or something to that effect.
Can you not? I know that systemctl has a userspace dot folder for user's services.
[0] `~/.config/systemd/user/`
https://docs.podman.io/en/latest/markdown/podman-systemd.uni...
I tried with Ubuntu just know and there's a 404 for buildah to install via apt at this exact moment. Here's my working Fedora WSL2 (which I prefer and use daily).
$ cat /etc/os-release
NAME="Fedora Linux"
VERSION="42 (WSL)"
RELEASE_TYPE=stable
ID=fedora
VERSION_ID=42
VERSION_CODENAME=""
PLATFORM_ID="platform:f42"
PRETTY_NAME="Fedora Linux 42 (WSL)"
...
VARIANT="WSL"
VARIANT_ID=wsl
[0] - https://www.redhat.com/en/blog/quadlet-podmanFor what it's worth, podman has also a thin wrapper around docker compose (podman compose) which can also automatically select `podman-compose`.
Note:
- `podman-compose` is an early attempt at remaking `docker-compose` but for Podman.
- Later Podman wrote a Docker compatible socket instead, which can work with most docker clis that accept a `DOCKER_HOST` argument, including `docker` and `docker-compose` (both v1 and v2)
- `podman compose` is a thin wrapper that automatically selects `docker-compose` or `podman-compose` depending on which is installed.
I use this on my server with compose together with traefik which listens on 127.0.0.1:{8000,4433}. Then I have a small nftables config that does the port forwarding to 80/443.
You just mentioned they are.
And that's just half of it. Want to build an image on two native architectures (ARM64 and AMD64) and then make a multi-arch image out of them. Might blow someones mind on how complicated that is with 2025 docker technologies: https://docs.docker.com/build/ci/github-actions/multi-platfo...
However, for single server deployments, where I don't need Kubernetes, I now exclusively use Quadlets to run apps and I couldn't be happier. It's a much nicer experience that using typical Docker/Podman setup. It feels integrated into the system.
You can mix them. I was using docker-compose with podman instead of docker before switching to quadlets. I still prefer the experience of compose files, but quadlets do integrate much better into systemd.
My usage is fairly basic though and I'm sure mileage varies, but for my basic web dev setup it's been perfect.
”just” is a big statement here. Performance between colima and OrbStack are from different planets.
Apple just released their own runtime so that is also worth inspecting.
I think I have just used the defaults. The difference was huge in regular use. E.g. simple test to upgrade OS packages and time that.
FWIW lima (upon which COlima was built) ships with "boot me up a podman": <https://github.com/lima-vm/lima/blob/v1.2.1/templates/podman...> and <https://github.com/lima-vm/lima/blob/v1.2.1/templates/podman...>
I can't think of any stellar reason why colima couldn't also support it, since they even go out of their way to support Incus as a runtime, but I don't currently have the emotional energy to prosecute such a PR
In particular the 1TB VM disk image OrbStack uses wreaks havok with deduplicating backups. Their disk cache also caused me hours of debugging why my assets weren't up-to-date.
Admittedly the OrbStack GUI is super snappy tho.
I think the better long-term approach though is to use systemd user units for deployment, or the more modern approach of using Podman Quadlets. There's a bit of a learning curve, but these approaches are more native to the Podman platform, and learning how systemd services work is a great skill to have.
One enhancement suggestion to TFA, would be to take a hash of the compose file path, then have that as a prefix name in a temp directory for a hash of the compose file itself... if the hash changes, dump the .json and rebuild in the temp path... then do the bakah against that file. This would be an easy enough script to make.
That's their prerogative, and I could build it myself, but it makes me concerned they don't really have multi-distro compatibility as a priority, which makes me hesitant to commit time to experimenting with it when Docker considers Ubuntu a first-class citizen.
apt-get -y install podman
Podman doesn't produce their own binary distributions for ANY Linux distro. The only binary packages they provide are for Mac and Windows because those don't have a native package repository.Even if they did release their own Linux packages, bear in mind that Podman development is driven by and sponsored almost entirely by Red Hat. It's not really in their interest to pay their developers to maintain packages for Ubuntu, a direct competitor in the enterprise Linux space.
> It's not really in their interest to pay their developers to maintain packages for Ubuntu, a direct competitor in the enterprise Linux space.
Exactly. :)
...
Also yes, podman v4 on bookwarm was famously useless in many cases and because of either libc or kernel (iirc) you could not even install v5 effortlessly.
I like Debian and I like podman but putting this as a usefule nice experience (up until trixie released) is just weird framing.
https://docs.docker.com/build/building/export/
Does Podman supports the same feature?
I have tried to find a good comparison between the two, but I find it hard to have a clear opinion on which one is best for me.
Very few distros ship the extras required for it. If yours doesn't, you'll have some extra manual steps to set it up.
On Mac it works ok to, but there are networking cases that Colima on mac doesn't handle - so orbstack for there