Request
- name: m0x41-podman
- description: Podman v5.8.1 container engine with all runtime dependencies bundled (crun, conmon, netavark, aardvark-dns, fuse-overlayfs, slirp4netns, catatonit). Supports rootless and rootful operation, including Quadlet (systemd integration). Built on core22.
- snapcraft: m0x41-podman/snapcraft.yaml at main · miah0x41/m0x41-podman · GitHub
- upstream: GitHub - containers/podman: Podman: A tool for managing OCI containers and pods. · GitHub
- upstream-relation: No upstream affiliation, I’m an independent packager. This snap packages unmodified upstream sources.
- supported-category: Development tool / container runtime.
Podman is a daemonless container engine used for developing, managing, and running OCI containers. Analogous to Docker. It requires host filesystem access for setuid binaries, library path propagation, and systemd generator registration, none of which are achievable under strict confinement.
I understand that strict confinement is generally preferred over classic.
I’ve tried the existing interfaces to make the snap to work under strict confinement.
Rationale
As the upstream project is mature and popular to which I have no formal relationship, I have no means to adapt it to meet the confines of Snap, therefore this is more of an attempt utilise Snap features to enable Podman to work within these constraints.
Strict confinement’s mount namespace replaces /usr/bin with the base snap’s copy, which breaks both rootless and rootful container operation through four fundamental constraints:
1. setuid newuidmap/newgidmap unreachable
The host’s setuid binaries (from the uidmap package) are hidden by the mount namespace. Staging them inside the snap does not work: snapcraft strips setuid bits during packing, squashfs mounts with nosuid, and file capabilities are also stripped. Without these binaries, rootless user namespace creation fails outright.
2. netavark path resolution failure
Podman discovers its network backend (netavark) via helper_binaries_dir, not the netavark_path configuration key. Under strict confinement the bundled binary cannot be found, so all container networking fails.
3. LD_LIBRARY_PATH lost across process boundaries
The snap wrapper sets LD_LIBRARY_PATH for Podman, but when Podman spawns conmon, which then spawns crun, the library path is not inherited. Bundled libraries such as libyajl (required by crun) are not found, causing every podman run to fail with an OCI runtime error.
4. policy.json path cannot be changed
Podman hardcodes two filesystem paths for policy.json and provides no environment variable override. Under strict confinement the snap cannot place the file at either expected location.
These four constraints block container execution in both rootless and rootful modes. No combination of existing
snapdinterfaces (system-files,personal-files, layouts,snapcraft-preload) resolves all four simultaneously. Thesystem-filesinterface cannot grant access to setuid binaries. Layouts cannot inject files into paths owned by the base snap. The library path propagation issue occurs across process boundaries thatsnapddoes not appear to control.
5. Snap runtime directory not created for non-interactive sessions
su - does not trigger a logind session, so snapd never creates /run/user/<uid>/snap.<snap-name>, breaking rootless operation when invoked via su or sudo -u.
6. Install hook cannot modify the host
Classic confinement enables the snap’s install hook to register systemd generators for Quadlet (systemd container integration) and place a podman shim on PATH at /usr/local/bin/podman. These operations write to /usr/lib/systemd/, /usr/local/bin/, and /etc/ld.so.conf.d/ — all prohibited under strict confinement. Without them, Quadlet does not work and users must invoke the snap by its full name rather than podman.
One of the key changes to v5 of Podman is the ability to orchestrate pods using Quadlets relative to v4 (currently in Ubuntu 24.04).
Please examine the public source repo for the full methodology and findings.