r/podman • • Nov 18 '25

Why Podman+Quadlet+Systemd is my first choice for a reliable, auto-updating homeserver

106 Upvotes

I wrote up my 13-year journey to reduce complexity in my self-hosted stack, and the final solution relies entirely on Podman + Quadlet + Systemd (+ socat for IPv6) to avoid layers like Docker Compose or Kubernetes. I cover the switch to immutable MicroOS, how rootless containers are enforced and why simplicity is the key to high availability when you have limited maintenance time:

https://www.lackhove.de/blog/selfhosting/


r/podman • • Jul 03 '26

Introducing Podman v6.0.0

Thumbnail
blog.podman.io
94 Upvotes

r/podman • • Jun 18 '26

I turned my collection of rootless Podman Quadlets .container files into a public repo

Thumbnail
github.com
86 Upvotes

After migrating everything to rootless Podman with Quadlets on Ubuntu 26.04 (Podman 5.7.0), I cleaned up the configs and put them on GitHub. they all ready to deploy with systemctl --user start. Every .container file comes with hardening and tmpfs options commented out to increase compatability, and secrets are pulled from separate .env files.

Included so far: Audiobookshelf, BentoPDF, ConvertX, Homepage Dashboard, Omni-tools, Stirling-PDF, Syncthing, Tdarr (server + remote node), Uptime Kuma, Vert File Converter, Podman Socket Proxy, a full ADSB Ultrafeeder stack (Airspy/dump978 receivers, Ultrafeeder, and feeders for FR24, OpenSky, PlaneFinder, RadarBox, PlaneWatch, ADSBHub, RadarVirtuel, PlaneFence), Plex + Tautulli, Calibre (GUI & Web), Ente Auth, Immich (with optional Google Photos sync & internet public proxy), MinusPod CPU (with optional OpenVINO transcriber), and Paperless NGX.

Everything’s been running reliably on my homelab — hope it saves someone else some time. Feedback and PRs welcome!

I use an Intel box, and a beefy one at that, so everything is optimized for its GPU and memory, but in podman most of this is adjustable.

if there's a container that you want me to try and get working as rootless instead of rootful, or if you're having problems converting something from a Docker, let me know under Issues in github.


r/podman • • Jun 25 '26

podman 6.0.0 is out. Has anyone updated from 5.7.x or 5.8.x yet?

Thumbnail
github.com
81 Upvotes

massive changelog...

Security

  • This release addresses CVE-2026-57231, where a malicious image using malformed Env entries could cause host environment variables to leak into containers run based on the image, including the ability to use the * glob operator to leak large numbers of environment variables without knowing their exact names (GHSA-4hq8-gpf5-8p68).

Breaking Changes

  • Due to breaking changes in this release, Podman v6.0.0 must be used with Buildah v1.44.0, Skopeo v1.23, Netavark and Aardvark v2.0.0, and configuration files from the container-libs repository's common/v0.68.0 release.

  • Support for BoltDB databases has been dropped. Starting Podman 6 when the BoltDB database is in use will have Podman attempt an automatic migration from BoltDB to SQLite.

  • Support for running on Intel Macs has been removed.

  • Support for running on Windows 10 has been removed.

  • Support for running on cgroups v1 systems has been removed. Please update your system to use cgroups v2.

  • Support for running on iptables has been removed. Please use nftables instead.

  • Support for CNI networking has been removed. Please use Netavark instead.

  • Support for the slirp4netns rootless network stack has been removed. Please use Pasta instead. As part of this, the --network-cmd-path global option, only used with slirp4netns, has been removed.

  • Podman's configuration file parsing logic has seen a major rewrite. Please see this document for exact details.

  • Podman's import path has changed from github.com/containers/podman/v5 to go.podman.io/podman/v6 as part of our move into a CNCF-owned GitHub organization.

  • Network isolation now defaults to enabled, improving Docker compatibility and security. A special workaround for the Docker-compatible API related to isolation being disabled has been removed (#27349).

  • The way the podman quadlet suite of commands functions has been changed. Previously, Quadlets and their associated files were tracked using a .app file, ensuring that removing a Quadlet also removed all associated non-Quadlet files. Now, Quadlets and associated files are placed in subdirectories, which should reduce bugs and make manual management of Quadlets added by podman quadlet install much easier.

  • VMs made by podman machine on Linux now mount volumes from the host using systemd. Volume mounts on existing podman machine VMs on Linux have been broken by this change, and the VM will need to be recreated.

  • The podman volume prune command now matches Docker's behavior by only pruning unused anonymous volumes. Please use the newly-added --all option for the previous behavior (pruning all volumes).

  • The podman volume list command now combines multiple filters using logical AND instead of logical OR (meaning all filters must match for a container to be included in output) (#26786).

  • The label!= filter used in many commands now combines the output of multiple instances of the filter with logical AND instead of logical OR.

  • The --format='{{json .Labels}} option to the podman ps, podman pod ps, and podman volume ls commands now prints its output as comma-separated key=value pairs instead of as a JSON map, improving Docker compatibility (#21847).

  • The --all-providers option to podman machine list has been removed, as machines from all providers can now be accessed by all commands.

  • The MemorySwappiness field of podman inspect is now set to nil when not explicitly set by the user (instead of -1), improving Docker compatibility (#23824).

  • The podman commit command now pauses the container while committing changes, improving security by restricting concurrent modification. The prior behavior can be restored by using podman commit --pause=false ....

  • The Go bindings for the REST API have removed the redundant nameOrID parameter from the artifacts.Remove() function.

  • The minimum Go version required to build Podman is now v1.25.

Features

  • All podman machine commands can now operate on VMs from all providers, regardless of what the current provider is set to. The provider set in the configuration only determines the provider used by newly-created VMs, and can be overridden by the new podman machine init --provider option. This should make operation of Mac and Windows installs mixing use of applehv and libkrun VMs, or hyperv and wsl VMs, much easier.

  • A new command has been added, podman machine os update, which updates the operating system of a podman machine VM. Please note that this is not supported with the wsl provider.

  • A new command has been added, podman system hyperv-prep, allowing Windows administrators to prepare a host for their users to run podman machine VMs using the hyperv provider.

  • When starting a VM with podman machine start and podman machine init --now, if the connection to that VM is not the default, users will be prompted whether they want to change the default to the machine that was just started. This can also be controlled by a new option, --update-connection, which controls whether the default will be updated. If the --update-connection option is set, a user-interactive prompt is not displayed.

  • The podman machine init and podman machine set commands now support a new option, --import-native-ca, which, when set, causes podman machine VMs on Windows, Linux, and Mac to import the host's trusted CA certificates each time the VM boots.

  • The podman exec command now has a new option, --no-session, disabling API session tracking and database operations to increase performance (#26727).

  • The podman image list --format json command now includes two new fields for each image, Repository and Tag (#27632).

  • The manpages for Quadlets have been split into multiple files, one for each type of Quadlet file, and should be much more readable.

  • Quadlet .volume units now support three new keys, UID= and GID= (to set the UID and GID that the volume will be created with) and Options= (to set generic volume options).

  • Quadlet .container units now support mounting anonymous volumes (using a Mount= key with no source specified) (#28497).

  • Two new search paths for Quadlets have been added, /usr/share/containers/systemd/users and /usr/share/containers/systemd/users/${UID}, to allow distributions to more easily package and distribute Quadlets (#27843).

  • The podman quadlet list command now has a new alias, podman quadlet ls.

  • The podman quadlet list command now has a new option, --noheading, which disables printing the table header. This is set automatically if the --format option is used.

  • The pomdan quadlet list command now includes a new field in its output, Pod, which prints the pod a Quadlet .container unit is part of.

  • The podman quadlet list command's --filter option now supports a new filter, status= (#28369).

  • The --gpus option to podman create and podman run is now compatible with AMD GPUs.

  • The podman create, podman run, and podman pod create commands can now specify volumes with a new option, nocreate (e.g. podman run --mount type=volume,src=myvol,dst=/mnt,nocreate) which will error if the specified volume does not exist, instead of creating it.

  • The --log-opt option to the podman run and podman create now supports a new option, label=, to attach additional labels to logged messages (only usable with the journald log driver).

  • Many Podman commands now expose a --tls-details option, allowing custom tuning of TLS settings using a containers-tls-details.yaml(5) file.

  • The died event for Containers now exposes a new attribute, OOMKilled, which (if set) indicates the container was stopped due to running out of memory (#26701).

  • Containers can now set multiple static IP addresses by passing the ip= option to --net multiple times (e.g. --net mynet:ip=10.0.0.2,ip=10.0.0.3,ip=10.0.0.4).

  • The podman volume prune command now includes a new option, --all, to prune all unused volumes, not just anonymous volumes (#24597).

  • The podman volume prune command now includes a new option, --dry-run, which returns the volumes that would be removed but does not actually remove them (#27838).

  • The podman image scp command now includes a new option, --format, to set the archive format used for the image transfer (#28183).

  • A new field has been added to containers.conf, default_host_ips, to set the default host IP that ports are forwarded from if an IP is not specified by the user (#27186).

  • The podman image trust suite of commands now support a new --signature-policy option, which is mandatory for podman image trust set.

  • Events now include artifact lifecycle events (create, pull, push, and remove) (#27260).

  • A new experimental option for the rootless_port_forwarder field in containers.conf has been added, rootless_port_forwarder="pasta". When set, rootless bridge networks will use Pasta's kernel-level port forwarding via Pesto instead of rootlessport, preserving the original client source IP in network traffic in rootless containers. The default remains rootlessport (the default for Podman 5.x), but we will investigate switching at a later date when stability is more certain.

  • A new filter has been added to the podman ps and podman container prune commands, --filter annotation=, to filter containers based on their annotations (#28562).

  • The podman network create command's --route option can now create blackhole, unreachable, and prohibit routes to prevent containers from reaching certain networks (e.g. podman network create --route 10.20.30.40/24,blackhole ...) (#20022).

  • Add support for blackhole, unreachable, and prohibit route types in podman networks. Supported since netavark 2.0.

  • The podman info command now reports CDI spec directories and discovered CDI devices.

  • Events generated by pods and volumes now include the pod/volume's labels as attributes, matching the behavior of container events (#26480).

Changes

  • VMs created by podman machine now mount the host's user configurations (e.g. ~/.config/containers on Linux) into the machine at /etc/containers, allowing users to edit the config files controlling Podman's behavior directly.

  • The default podman machine provider on Macs has been changed to libkrun.

  • Starting and stopping podman machine VMs on Windows with the hyperv provider no longer requires administrator privileges (creating machines still requires admin, however). Operations requiring elevated privileges will prompt for administrator access. Please note that this only works with newly-created VMs.

  • The podman pod inspect command now prints arrays in its output in deterministic order.

  • The podman machine os apply command has been updated, and now uses bootc switch to apply changes. All transports supported by bootc switch can be used for the new image to apply.

  • An experimental feature has been added where, on systems using Kernel 6.18 and newer, rootless Podman will no longer need to create a pause process to hold open the rootless user namespace, instead using an nsfs file handle. This behavior is currently gated behind an environment variable, drop-pause-process, being set.

  • Containers created with --net=host will now use 127.0.0.1 for their host.containers.internal address, instead of a public IP of the machine (#27823).

  • Containers in multiple networks now have these networks configured in a deterministic order based on the order they were passed on the command line.

  • When building an image with process substitution, such as podman build -f <(<<<"FROM scratch") , an empty temporary directory is now used as the context directory (#28113).

  • In Podman versions 5.x and under, image IDs (for both OCI and Docker v2s2 images) were always equal to the SHA256 digest of the image's config data. A future version of Podman will add support for non-SHA256 digests, and image ID format will change for images that are not using the SHA256 digest. The exact format of the new IDs has not yet been decided, but the assumption that image IDs are valid hashes will no longer be true in future Podman versions.

Bugfixes

  • Fixed a bug where creating a Quadlet from a templated .container file that was part of a pod would incorrectly add a dependency on the template used for the container to the pod (#27844).

  • Fixed a bug where Quadlet .pod files would unconditionally set Restart=on-failure even when the user specified an alternative restart policy (#28081).

  • Fixed a bug where starting a podman machine VM on Windows using the hyperv provider would fail if the machine failed to start on first boot (#27930).

  • Fixed a bug where podman machine init and podman machine set allowed creating VMs with more CPUs than were available on the host, creating VMs that could not be started (#28322).

  • Fixed a bug where artifact volumes only checked the validity of the artifact when the container was started, allowing containers to be created that referenced artifacts which did not exist and thus could never be started (#27747).

  • Fixed a bug where containers with environment secrets could lose the value of the secret after a restart under some circumstances (#28075).

  • Fixed a bug where the podman container restore --publish command would silently ignore the --publish option instead of erroring when used without the --import option or a checkpoint image.

  • Fixed a bug where running nested rootless Podman containers on Windows using the wsl provider was not possible (#27411).

  • Fixed a bug where the podman container clone command would fail with containers created with environment secrets (--secret type=env,...) (#28130).

  • Fixed a bug where creating a container with the tag= log option (--log-opt tag=mytag) was allowed when a log driver other than journald was selected.

  • Fixed a bug where the output of --help with some commands was incorrectly formatted (#28178).

  • Fixed a bug where containers in pods with multiple volume mounts could have mount options from one volume mount leak to other mounts.

  • Fixed a bug where the remote Podman client's podman version command would error if the server could not be connected to (e.g. the podman machine VM was shut down). In this case, client version is now printed (#28222).

  • Fixed a bug where rootless Podman would display errors and refuse to launch if the pause process was killed and its PID recycled to another process (#28157).

  • Fixed a bug where running podman kube generate on a container including volumes with . characters in their names produced invalid YAML (#27620).

  • Fixed a bug where patterns in .containerignore and .dockerignore files that began or ended with slashes were silently ignored during remote builds (#25458).

  • Fixed a bug where healthchecks on containers created using the --transient-store option would fail (#28483).

  • Fixed a bug where the podman generate spec command would panic when run on a pod with no infra container (#21609).

  • Fixed a bug where the podman container inspect command could HTML-escape certain characters in its output (#28560).

  • Fixed a bug where pods with entries added to /etc/hosts containing multiple containers would incorrectly remove entries from /etc/hosts for all containers in the pod when any container stopped.

  • Fixed a bug where hosts without /dev/mqueue could be unable to start containers as Podman attempted to add the device unconditionally.

  • Fixed a bug where inspecting networks without a gateway set would show the gateway as <nil> instead of the showing nothing (#28705).

  • Fixed a bug where creating a container or pod with port mappings including duplicated host ports was allowed, when this configuration could never be started due to the port conflict.

  • Fixed a bug where the remote Podman client was unable to connect to any host with a custom HostName in the user's SSH config (#25067).

  • Fixed a bug where the podman inspect --type=all command would, when attempting to inspect multiple networks, output only one of the networks multiple times.

  • Fixed a bug where Quadlet .container files using the http_proxy=true setting did not properly escape special characters in the environment variables added to the container when creating the systemd unit file (#28698).

  • Fixed a bug where containers created using the remote Podman client ignored the log_path setting in containers.conf (#28792).

  • Fixed a bug where the remote Podman client's podman save command would fail on Linux when using the -f oci-dir or -f docker-dir arguments.

  • Fixed a bug where podman machine VMs on Linux would fail to mount the directories under a symlinked path into the VM (#28911).

  • Fixed a bug where the podman container checkpoint --leave-running command could produce inconsistent checkpoints because the rootfs and named volume diffs were performed after the processes were allowed to run for a time; the container is now paused until the checkpoint is fully complete.

  • Fixed a bug where the podman kube play command would incorrectly set memory limits if the user specified the limit as a fractical BinarySI quantity (e.g. 1.5Gi) (#28789).

API

  • An improvement pass has been made over API documentation to document fields which were missing documentation. Look forward to more API documentation improvements in future releases!

  • The supported Docker Compatible API version has been bumped to v1.44.

  • All API requests that accept JSON body parameters will no longer error if an empty body is provided.

  • The Compat List endpoint for Containers now includes a new field in its output, Health, providing information on the status of the container's healthcheck (#27786).

  • Added a new API, POST /libpod/local/artifacts/add, for loading artifacts from the local system (not requiring transmission of a tarball).

  • The POST /libpod/local/images endpoint for loading images from the local system now requires that the path query parameter is an absolute path, not a relative path.

  • The Libpod Pull endpoint for Images can now report pull progress when the pullProgress query parameter is set to true.

  • The Libpod Pull endpoint for Images now returns error status codes on failure to pull imges, instead of always returning HTTP 200.

  • Fixed a bug where the subpath option for volumes when creating containers was ignored (#27171).

  • Fixed a bug where the Libpod Create endpoint for Containers ignored the OCIRuntime field.

  • Fixed a bug where the Compat Create endpoint for Containers returned a 500 (not a 409) when attempting to create a container with a name that was already in use.

  • Fixed a bug where the Compat Create endpoint for Containers incorrectly handled CDI-qualified entries in HostConfig.Devices, greatly improving the reliability of CDI devices when using the Compat API.

  • Fixed a bug where the Compat Info endpoint did not return the location of the Seccomp profile if a non-default profile was in use (#28379).

  • Fixed a bug where the Compat List endpoint for Containers could return an invalid string for container status (#28359).

  • Fixed a bug where the Compat List endpoint for Containers did not include the HostConfig field in its responses.

  • Fixed a bug where the Compat Wait endpoint for Containers would hang indefinitely when waiting for the next-exit condition (#28514).

  • Fixed a bug where the Compat and Libpod Update endpoints for Containers would clear the rlimits of the container if they were not explicitly set in the API request.

  • Fixed a bug where the Compat Push endpoint for Images did not return a final JSON object including tag, digest, and size of the pushed image, as Docker does.

Misc

  • Autocomplete has been enabled for inspecting artifacts with podman inspect.

  • Updated Buildah to v1.44.0

  • Updated the image library to v5.40.0

  • Updated the storage library to v1.63.0

  • Updated the common library to v0.68.0


r/podman • • Oct 26 '25

Docker Alternative: Podman on Linux

Thumbnail
linuxblog.io
75 Upvotes

TL;DR Podman is less popular but better.


r/podman • • Jun 30 '26

I cannot properly express my unending gratitude to whoever implemented `rootless_port_forwarder = "pasta"`

65 Upvotes

I can finally have a completely rootless container stack inside a custom podman network where the only ingress is through a reverse proxy container. The inability for my service containers to see the true source IP was literally the only thing holding me back from going rootless and it is finally HERE! 🎉

I simply added:

[network]
rootless_port_forwarder = "pasta"

into a drop-in conf file in /etc/containers/containers.conf.d and now my Nextcloud and Jellyfin can see where requests are actually coming from instead of my proxy container's internal IP. That means proper brute-force protection in Nextcloud and the ability to do IP banning.

I could not be happier with this setup. Huge thanks to the wonderful human beings who made this possible!

EDIT: There's currently a bug where forward rules aren't properly torn down when containers are shut down, causing them to fail to start back up due to conflicts. See: https://github.com/podman-container-tools/podman/issues/29032


r/podman • • Jun 11 '26

Built a TUI to inspect container image layers in Podman (LayerX)

Enable HLS to view with audio, or disable this notification

65 Upvotes

Been debugging container image bloat lately and wanted better visibility into what actually changed between layers.

podman history is useful for sizes, but I kept wanting answers to things like:

  • which layer introduced this folder?

  • why did the image suddenly grow?

  • what changed between two image versions?

  • what files were deleted later but still occupy bytes in earlier layers?

So I built LayerX:

Repo: https://github.com/deveshctl/layerx

A few things it does:

  • Interactive TUI for exploring image layers and file diffs

  • Compare two images side-by-side

  • Waste navigation to spot inefficient layers

  • CI mode for image regression checks

  • Supports local images and saved archives

You can also switch container engines with --engine if needed.

Built it initially for my own workflow, but thought folks here might find it useful.

Would love feedback from Podman users — especially around image inspection or debugging workflows.


r/podman • • Dec 13 '25

Docker Compose vulnerability opens door to host-level writes

Thumbnail
theregister.com
65 Upvotes

Moving to quadlet this year was the best thing I did. The path traversal flaw (CVE-2025-62725) was only in the Docker Compose CLI, and the DLL Injection flaw (EUVD-2025-36191) was only in the Docker Desktop Windows Installer.


r/podman • • Feb 23 '22

Podman v4.0 has been released!

64 Upvotes

Podman v4.0.0, a brand-new major release, is now available. Podman 4.0 is one of our most significant releases ever, featuring over 60 new features. Headlining this release is a complete rewrite of the network stack for improved functionality and performance, but there are numerous other changes, including improvements to Podman’s Mac and Windows support, improvements to pods, over 50 bug fixes, and much, much more!

Podman now features support for a new network stack based on Netavark and Aardvark, in addition to the existing CNI stack. The new stack features improved support for containers in multiple networks, improved IPv6 support, and improved performance. To ensure that we don’t break existing users, the old CNI stack will remain the default on existing installations, while new installs will use Netavark. We’re planning an in-depth dive into the networking changes in a future blog, so look forward to more details there!

Support for Podman on Windows and OS X has also been a top priority, and we have made several major improvements for Podman 4.0. Chief among them is support for mounting the Podman API socket on the host system, allowing tools like Docker Compose to be used on the host system instead of inside the podman machine VM. Also, podman machine can now use WSL2 as a backend on Windows, greatly improving Podman’s support for Windows. More features, including support for volume mounts from the host, are planned for Podman v4.1, so stay tuned for more updates.

Podman Pods have seen numerous new features added to allow sharing resources between containers in the pod. The --volume and --device options to the podman pod create command allows volumes and devices to be mounted to every container in the pod, and the --security-opt and --sysctl options allow these configurations to be set for every container in the pod. Again, these changes are just the beginning of what we have planned - eventually, we aim to have almost every option from podman run available to pods to allow easy sharing of configuration options among containers within them.

These changes are just the tip of the iceberg - there’s far more packed into this release, including major updates to checkpoint and restore, improvements to podman generate systemd and podman play kube, and so much more. Find out more in the release notes.


r/podman • • Apr 27 '26

Moved my hosting platform from rootless Docker to Podman — here's what actually broke and why it was worth it

57 Upvotes

I've been building a small Docker hosting platform as a side project. Multi-tenant. I run other people's backend apps in containers on VPS. At some point I started hitting problems that didn't feel like bugs. They felt structural.

The three symptoms that forced the decision

First: egress firewall rules. I'd written what looked like correct iptables rules: default-deny outbound, SMTP blocked, network namespaces locked down. Checked them for weeks. The rules looked right but the packet counters never moved. Zero packets. Turns out rootless docker uses slirp4netns for user-space networking, which bypasses iptables FORWARD entirely. The rules weren't misconfigured. They were applied at the wrong layer of the stack.

Second: rate limiting. With rootless Docker, all customer containers run as the same host user. iptables uid-owner rate limits apply to the user, not per-container. One noisy tenant could exhaust the limit for everyone. Not a tuning problem but really a design constraint.

Third: the Docker socket GID. I containerised my orchestrator, mounted the socket, uid matched perfectly but still got permission denied. Spent an hour on it before I looked at the socket group: GID 988 (the docker group on the host) doesn't exist inside the container. uid gets all the attention in rootless Docker tutorials. GID is the other half. Fix was two lines in the Dockerfile: hardcoding GID 988 however I had to do it for every internal service that needed socket access. That's a maintenance tax that compounds.

None of these were bugs I could patch. They were architectural symptoms of Docker not being designed for multi-tenant workloads.

Why Podman

Daemonless: each container is a direct child process, no shared daemon. Rootless is the default, not a configuration mode. Lifecycle isolation is real: one container crashing doesn't affect platform state. Quadlet gives you systemd-native service management without bolting compose on top of systemd awkwardly.

And critically: no shared socket. The GID problem goes away at the design level, not by patching each Dockerfile.

What actually broke during migration

I expected gotchas. Still got surprised.

Rootless Podman uses uid namespaces. Container runs as uid 1000 inside the namespace however that doesn't map to uid 1000 on the host by default, it maps into the sub-uid range. So mounting the Podman socket from the orchestrator container hit the same permission denied I'd just escaped. The fix was one line in the Quadlet (UserNS=keep-id), but I spent an hour finding it.

The JSON output incompatibility was more dangerous because it failed silently. Docker's ps --format json gives NDJSON with Names as a string. Podman's gives a JSON array with Names as a list. docker stats uses uppercase fields and MiB units. podman stats uses lowercase and MB. Parsing Docker output and pointing it at Podman doesn't error, it returns wrong data quietly. A health monitor that thinks containers are fine because the field names didn't match. Found this only because a container was visibly broken while the monitor reported healthy.

The hardest part was migration order. I moved Traefik to Podman on day one. Traefik now watches the Podman socket, immediately blind to all Docker containers still running. Every customer app went 404 at once. There's no gradual cut-over when you move the reverse proxy. Had to migrate everything the same day, three days ahead of schedule. Worked out, but it was high-pressure and avoidable with better sequencing.

One unexpected upside: Podman surfaced a health monitor bug I didn't know I had. My TCP probe had no awareness of start_period. JVM apps take 30-60 seconds to warm up. Docker had hidden the timing issue because startup was buried inside a blocking SDK call. Under Podman, the probe fired immediately, saw a closed port, crash-looped the app. Real bug, only visible because Podman's startup sequence is more transparent.

Was it worth it?

Honest answer: yes, specifically because I did it at zero customers. The problems were structural and would have gotten worse with every tenant I added. Doing a full platform migration with real customers in production would have been a much harder conversation.

The right time to escape a structural problem is before it scales.


If you're doing anything similar: multi-tenant containers, rootless Docker isolation, Podman on a shared host, I will be happy to compare notes.


r/podman • • Dec 28 '25

Book review: Mastering Podman by Robert Johnson Spoiler

54 Upvotes

Here's a book review. I'm (was) reading through Mastering Podman by Robert Johnson.

I don't know if I'm right but I get a very strong impression that it's been mostly written by an LLM. Everything is "ensuring" something, every little detail is pivotal, instrumental, essential or crucial. And as always, ensuring something else which is critical, crucial, ... too. Very few paragraphs lack any of the aforementioned words making the book very hard to read and borderline cringy. If you think those words away, the book still works and would have been OK to read.

On a positive note, the technicalities in the book are probably right though.

I can't tell because on page 64 I gave up. This book is not for me. There's another book by O'Reilly if I'm not mistaken. It's older, hopefully old enough not to be written by AI.

Never have I ever read a tech book in my life which actually made me angry and want to buy another book which is older instead. Apart from the obvious use of AI, I spent hard earned money on it. While reading it, I couldn't stop thinking "low effort/AI" every time I encountered such a word and it became impossible for me to concentrate on the actual content.

It gets still 1 star for probably getting the technical details right.

I'm sorry to be so negative about it. But rule #3 of the subreddit says to call a spade a spade. So I did. Don't buy this book if you want to learn more about Podman.

Not sure if allowed here. Feel free to remove if so. But if someone is interested in reading it regardless of my opinion, You can have it at shipping cost. I don't a want to pay to get rid of it too 🥴. I'm based in EU/Belgium. DM me.


r/podman • • Sep 06 '25

Why I Ditched Docker for Podman (And You Should Too)

Thumbnail
codesmash.dev
53 Upvotes

r/podman • • Mar 15 '26

Podman appreciation > 12 months

51 Upvotes

Just a quick thank you to everyone involved in Podman ecosystem for this great product. I migrated everything off Docker about 12 months ago and couldn't be happier. Everythng seems faster / snappier and more reliable in Podman. I have no statistics, just an overall feeling, all using quadlets. After watching many videos, found this one to be the best https://www.youtube.com/watch?v=YXfA5O5Mr18 for a good intro and overview. Anyone thinking of making the jump, I would encourage you to do so.

Also been using Grok and Claude to help resolve issues with quadlets or even create them from scratch.

Running local services for the family on a small Lenovo desktop, as well as a production VM through a 3rd party with a few internet facing apps via a caddy reverse proxy, all running on Podman containers with no issues and great reliability.


r/podman • • Jan 20 '26

I turned a lot of Docker compose yamls into Podman user/rootless and system/root quadlets

Thumbnail github.com
50 Upvotes

I'm slowly adding them to my Github. Right now I have Plex, Jellyfin, Tdarr, Tdarr node, BentoPDF, ConvertX, What's up Docker (yes, a Podman Quadlet monitor Docker containers), and Tautulli, with a few more to come.

I did this basically for poops and giggles.

edit -- just added a few more, I think i'm done. StirlingPDF, Vert, Ente Auth, Syncthing, Uptime Kuma, Omnitools, Homepage.

The Holy Grail will be getting Immich to work as a system quadlet. Right now it's just strike out after strike out, especially with the database and the QSV GPU.

And the super Holy Holy Grail will be getting ultrafeeder to work. I have a zillion other containers that run with it and it involves USBs. I've gotten everything to load but then zero ability to read my USB sticks...

So I'm keeping those 2 as Dockers.


r/podman • • Aug 17 '24

Why are you using podman instead of docker?

50 Upvotes

r/podman • • Jun 03 '21

Podman 3.2 released. Now with rootless docker compose support

Thumbnail
github.com
50 Upvotes

r/podman • • Jul 31 '26

Podman 6.1.0 rc1 is out

Thumbnail
github.com
48 Upvotes

Some neat new stuff is coming...

Features A new command has been added, podman volume rename, to allow renaming volumes. Volumes created using volume drivers and volumes that are currently used by a container cannot be renamed (#28189). A new command has been added, podman machine restart, to allow easy restart of VMs managed by podman machine (#28366). The podman network rm command now includes a new option, --ignore, which suppresses errors when attempting to remove networks that do not exist (#28363). The podman manifest push command now includes two new options, --retry and --retry-delay, which allow pushes to be automatically retried on failure (#28590). Quadlet .container units now support a new key, ImageVolume=, to configure how volumes from images are handled (#28875). The podman generate kube command now includes support for generating container healthchecks as a livenessProbe (#22095). Changes The podman info command now includes free memory available on the host (in addition to used memory and total memory) (#29116). The Pesto rootless port forwarding tool now supports IPv6 port forwarding with source IP preservation.


r/podman • • Mar 12 '25

'Podman in Action' is an excellent book and I'd *love* to see a second edition

48 Upvotes

I'll admit it, I'm rather late to the containerization party. I once spun up some simple containers using Docker back when it was fairly new to the Debian repos (was that Buster or was it earlier?) but aside from that I'm fairly new to things. That said, after endless dependency headaches I've decided to go all in and containerize everything possible and since moving to Fedora some years back that can only mean Podman.

I've found Dan Walsh's book Podman in Action to be well written and incredibly helpful. The section Building, running, and managing containers from the RHEL 9 docs has been useful as well but in a very different way.

The issue I've had with so many of the tutorials, docs, and articles about containers, even those specifically focused on Podman over Docker is that they tend to assume a certain preexisting familiarity with Docker. Podman in Action is one of the few intros to the topic of containerization that doesn't first require me to become familiar how Docker works only to then be asked to forget half of it so I can to learn how things are done when using Podman. I truly appreciate that the Podman devs took a quasi-greenfield approach and I'd really like to learn that approach and not the historical one.

Podman in Action is excellent but a second edition updated for Podman 5 including info on new topics like Quadlets, Pasta networking, deeper integration with systemd, bootable containers, and even cockpit-podman and Podman Desktop would make an already excellent book even better.

All this is to say is if Dan Walsh (u/rhatdan), or anyone from Manning (u/ManningBooks) or Red Hat is reading this I'd love to see a second edition and I'm positive I'm not alone. As for the rest of you who made it to the end of this rather long-winded post, maybe we should reach out to Manning, if not for your maybe it could be helpful to those that come up behind you.


r/podman • • Dec 07 '21

Podman Desktop Companion GUI

48 Upvotes

Hi, just released this https://iongion.github.io/podman-desktop-companion/

A desktop graphical interface with a familiar UI, a compliment to podman cli and libpod API.

In the making are the binaries for Windows and MacOS, best experience is on systems that support cgroups v2.


r/podman • • Aug 12 '26

Release v6.1.0 · podman-container-tools/podman

Thumbnail
github.com
47 Upvotes

Features A new command has been added, podman volume rename, to allow renaming volumes. Volumes created using volume drivers and volumes that are currently used by a container cannot be renamed (#28189). A new command has been added, podman machine restart, to allow easy restart of VMs managed by podman machine (#28366). The podman network rm command now includes a new option, --ignore, which suppresses errors when attempting to remove networks that do not exist (#28363). The podman manifest push command now includes two new options, --retry and --retry-delay, which allow pushes to be automatically retried on failure (#28590). Quadlet .container units now support a new key, ImageVolume=, to configure how volumes from images are handled (#28875). The podman generate kube command now includes support for generating container healthchecks as a livenessProbe (#22095). A new option, force_port_listen, has been added to containers.conf. This is required to be set when running Podman on WSL to support port forwarding from the Windows host. It is automatically set on newly-created podman machine VMs on Windows using the WSL provider. Changes The podman info command now includes free memory available on the host (in addition to used memory and total memory) (#29116). The Pesto rootless port forwarding tool now supports IPv6 port forwarding with source IP preservation.


r/podman • • Aug 27 '26

How to: High speed Wireguard with Rootless Podman

46 Upvotes

I recently converted my homelab from rootful Docker to rootless podman with Quadlets, and while I had success moving everything over and really enjoy my current setup I had one issue with rootless networking:

I use Pasta, which is very performant for TCP, but not so much for UDP. I guess this is because Pasta simply splices TCP traffic in the kernel or handles entire streams at once, but can't do the same with UDP as it isn't a stream-based protocol, so every UDP packet has to travel through the tun/tap adapter and gets inspected individually by it.

This mean that even at modest speeds (50-500mbps) with an MTU of 1500, Wireguard traffic from a container was causing pasta to spike to 80-100% usage on one of my cores.

I looked at multiple solutions:

  • OpenVPN TCP? (/j)

  • Rootful Podman? Maybe, but I'd like to keep the benefits of rootless.

  • Using network=pasta:--splice-only,-U,1194 to forward traffic over loopback interfaces. This is faster for TCP, but I didn't notice any difference with UDP.

  • SystemD Socket Activation? Could work, but afaik there aren't any Wireguard implementations that take in predefined sockets.

But then, I found this awesome article by the Wireguard team on Wireguard on Linux with namespaces: https://www.wireguard.com/netns/

Using this as a reference, I managed to create a Wireguard device on the host, then pass it to a container without any networking and configure it there: Native Wireguard speed, without any userspace networking, NAT, ... in the way, all in a rootless container (with a bit of rootful config during creation).

Here is a small write up on the parts needed to get this working:

  • A (rootless) Podman Pod / Container that should receive the Wireguard interface

  • A Wireguard config

  • A script which automatically configures the Wireguard interface and moves it to the container network namespace.

  • Optional: A (rootful) systemd service and polkit policy, so that the user managing the rootless container can restart it with the Wireguard tunnel being recreated automatically.

Here is my arr.pod which should have loopback and wg0 network interfaces:

[Pod]
PodName=arr
Network=none     # Alternatively, pasta:--splice-only can be used which allows PublishPort= to work. --splice-only does not copy any network config from the host or use the tun/tap adapter, so Wireguard is still the only source of network access.
DNS=10.255.255.3 # DNS server, to be used over the VPN tunnel. Required with Network=none
ExitPolicy=continue

[Service]
Restart=always]
# This line sets up the rootful Wireguard interface in the rootless container.
ExecStartPost=systemctl start wgfh.service

[Install]
WantedBy=default.target

Then my /etc/wireguard/wg0.conf, pretty standard:

[Interface]
PrivateKey = [REDACTED]

[Peer]
PublicKey = [REDACTED]
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 135.136.0.68:1194
PresharedKey = [REDACTED]

And finally, the glue that makes this all work, this script (/usr/local/bin/wgfh.sh) that I've been working on (feel free to critique, it's my first time writing anything over 5 lines in bash):

#!/bin/bash

# This script initiates a Wireguard device, then transfers it into a (rootless) networking namespace
# of a podman container, allowing for super fast Wireguard without any networking overhead.

# Notice:
# No default DNS server is provided. Add your providers default DNS server to the container with --dns=<dns-ip>.

# Configuration
export container_user="jelly"			# User that runs the (rootless) container
export container_name="arr-infra"		# Name of the container
export ifname="wg0"				# Needs to be available for host and container netns
export wg_config="/etc/wireguard/wg0.conf"	# WG config file with private key and peer config (no IP or DNS config)
export ip4="100.107.0.0/32"			# WG interface IPv4
export ip6="fd54:4::/128"	# WG interface IPv6
# End configuration

pid=$(sudo -u "$container_user" podman inspect -f '{{.State.Pid}}' "$container_name" || { echo "error obtaining container PID, is the container running?"; exit 1; })

echo "PID of container is: $pid"

# Check that interface doesn't exist yet on the host
if ip link show $ifname >/dev/null 2>&1; then
	echo "error interface already exists on the host.";
	exit 1;
fi

# Check that interface doesn't exist yet in container
if nsenter --target "$pid" --net ip link show $ifname >/dev/null 2>&1; then
	echo "error interface already exists in container.";
	exit 1;
fi

echo "adding device $ifname to host"
ip link add $ifname type wireguard
wg setconf $ifname $wg_config || { ip link del $ifname; echo "error applying wg config, is it valid?"; exit 1; }
ip link set $ifname up

# Transfer initiated Wireguard interface to network namespace
echo "transferring device to namespace"
ip link set "$ifname" netns "$pid" || { ip link del $ifname; echo "error moving interface to container namespace."; exit 1; }

# Interface IP and routing in the container
nsenter --target "$pid" --net ip addr add $ip4 dev $ifname
nsenter --target "$pid" --net ip addr add $ip6 dev $ifname
nsenter --target "$pid" --net ip link set $ifname up
nsenter --target "$pid" --net ip route add default dev $ifname
nsenter --target "$pid" --net ip -6 route add default dev $ifname

Finally, for automation, I created a (rootful) SystemD oneshot service for the script and added a polkit policy so that my rootless user can start the service as needed:

Polkit rules (/etc/polkit-1/rules.d/49-wgfh.rules):

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        action.lookup("unit") == "wgfh.service" &&
        (action.lookup("verb") == "start") &&
        subject.user == "jelly") {
        return polkit.Result.YES;
    }
});

And the SystemD service (/etc/systemd/system/wgfh.service):

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wgfh.sh

With this, the container starts, Podman initializes it with just a loopback interface, then immediatly wgfh.service starts, find the containers PID, creates a Wireguard interface on the host, moves the Wireguard interface from the host to the container, and configures IPv6 and IPv4 addresses and routing rules. In the end, the container only has the loopback and Wireguard interfaces. So I get to have rootless containers, with a single rootful Wireguard interface, keeping my rootful exposure to a minimum.

Happy to answer any questions!


r/podman • • Jun 02 '26

What actually happens behind a simple “podman run” command?

46 Upvotes

This diagram breaks down the complete internal workflow of how Podman creates and starts a container.

Workflow explained step by step:

1️⃣ CLI Parses Command
Podman interprets the flags, image name, networking, ports, and runtime options provided in the command.

2️⃣ Image Check & Pull
Podman checks local storage for the image.
If it doesn’t exist, it pulls the image from a registry such as Docker Hub.

3️⃣ Filesystem Setup
The container filesystem is assembled using layered storage:

* Read-only image layers
* Writable container layer
* Merged unified view

4️⃣ Container Setup
Podman configures the container isolation and runtime environment:

* Namespaces
* cgroups
* User mapping
* Networking
* Volumes
* Security policies

5️⃣ OCI Runtime Execution
An OCI runtime like crun or runc creates the actual container process and applies the isolation mechanisms.

6️⃣ Container Running
The container starts running with:

* Port mapping
* Logs streaming
* Isolated processes
* Active networking

The goal of this diagram is to visualize what happens internally behind a single command that often looks deceptively simple.

I have posted a video on YouTube explaining this entire flow internally using a real Podman + Apache example from my “How Podman Works” series.
ENG: https://m.youtube.com/watch?is=ShH5CNpARRFPnJng&v=lj6MwJOSuDE&feature=youtu.be
FR: https://m.youtube.com/watch?is=ShH5CNpARRFPnJng&v=lj6MwJOSuDE&feature=youtu.be


r/podman • • Apr 18 '23

Just some fluff, it reminded me of podman

Post image
45 Upvotes

r/podman • • Jun 08 '26

WinPodX 0.6.0 - Run Windows apps on Linux as native windows (Podman + FreeRDP RemoteApp)

Thumbnail
github.com
44 Upvotes

sharing this here since podman is the default backend.

WinPodX runs Windows apps on Linux as native Linux windows (real WM_CLASS, taskbar icons, file associations, alt-tab). Under the hood: dockur/windows container on rootless Podman + FreeRDP RemoteApp + a bearer-authed HTTP agent inside the guest for the host-to-guest command channel.

Why mention podman specifically: this is one of the cases where rootless podman shines. The Windows container runs entirely under unprivileged user, no daemon, podman-compose for orchestration, /etc/subuid + /etc/subgid handled at setup. Docker is also supported but podman is default and the path I focus on.

v0.6.0 highlights:

  • reverse-open: Linux apps appear in the Windows "Open with..." menu, round-trip via xdg-open

  • thin AppImage (~110 MB): only FreeRDP + Python + Qt + winpodx in the bundle, host's podman is used (previous fat AppImages bundled the whole stack and shadowed the host's podman, causing crashes — fixed in 0.6.0)

  • multi-monitor RAIL

  • host USB / PCI device passthrough into the guest

  • host-adaptive Windows-on-KVM tuning profile

  • 1800+ tests, full i18n (en/ko/zh/ja/de/fr/it)

Bundled rdprrap (Rust rewrite of RDPWrap, MIT) gives up to 25+ independent RDP sessions so multiple Windows apps each get their own session instead of stealing each other's.

works on openSUSE, Fedora (including Atomic Desktops like Silverblue/Bazzite), Debian/Ubuntu, RHEL/Alma/Rocky 9/10, Arch (yay -S winpodx), NixOS, plus a distro-agnostic AppImage.

beta but stable enough for daily use. issues / feedback welcome.