Rootless Podman, volumes and userns mapping
Second day of my current vacation and I’m already dabbling in container shenanigans.
The problem
I was trying to add something to my blog using a simple docker-compose.yml I
wrote for that purpose:
services:
hugo:
image: ghcr.io/hugomods/hugo:base-non-root-0.146.6
container_name: hugo
volumes:
- ".:/src"
ports:
- "1313:1313"
entrypoint: "hugo server -D --bind 0.0.0.0"
This allows me to only need Docker Compose instead of making sure that my blog
always conforms to the latest hugo version.
On the laptop I’m currently using, Docker was not installed so I decided to
give Podman and podman-compose a try, seeing as my Compose file seemed
simple enough.
Alas, on the first naive run I got the following error message:
$ podman-compose up
Watching for changes in /src/{archetypes,content,layouts,static,themes}
Watching for config changes in /src/config.toml
Start building sites …
hugo v0.146.6-1e0b058efe8d6e236bc7c8d6981d9bfb1443178e+extended linux/amd64 BuildDate=2025-04-20T10:58:40Z VendorInfo=hugomods
Built in 0 ms
Error: error building site: failed to acquire a build lock: open /src/.hugo_build.lock: permission denied
Running the pure podman run equivalent leads to the same error:
$ podman run --volume $(pwd):/src --publish 1313:1313 ghcr.io/hugomods/hugo:base-non-root-0.146.6 server -D --bind 0.0.0.0
Watching for changes in /src/{archetypes,content,layouts,static,themes}
Watching for config changes in /src/config.toml
Start building sites …
hugo v0.146.6-1e0b058efe8d6e236bc7c8d6981d9bfb1443178e+extended linux/amd64 BuildDate=2025-04-20T10:58:40Z VendorInfo=hugomods
Built in 0 ms
Error: error building site: failed to acquire a build lock: open /src/.hugo_build.lock: permission denied
Solution for podman run
A bit of research in the podman-run documentation led me to this information:
keep-id: creates a user namespace where the current user’s UID:GID are mapped to the same values in the container. For containers created by root, the current mapping is created into a new user namespace.
In addition, the init process within the container will run under the current user’s UID. This behavior overrides the image’s USER instruction unless you explicitly set –user.
This seems like the behavior I need!
Adding --userns=keep-id this to the above podman run command solves the permission
issue:
$ podman run --userns=keep-id --volume $(pwd):/src --publish 1313:1313 ghcr.io/hugomods/hugo:base-non-root-0.146.6 server -D --bind 0.0.0.0
Watching for changes in /src/{archetypes,content,layouts,static,themes}
Watching for config changes in /src/config.toml
Start building sites …
hugo v0.146.6-1e0b058efe8d6e236bc7c8d6981d9bfb1443178e+extended linux/amd64 BuildDate=2025-04-20T10:58:40Z VendorInfo=hugomods
[...]
Built in 36 ms
Environment: "development"
Serving pages from disk
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 0.0.0.0)
Press Ctrl+C to stop
Success!
But what about podman-compose?
According to a Github comment
I should be able to add userns_mode: keep-id in my docker-compose.yml, but
that didn’t work:
$ podman-compose up
Error: --userns and --pod cannot be set together
Searching for that error lead me to the same Github issue and further down it
was mentioned that Podman assumes in-pod to be true by default. This instructs
Podman to create new pod using the project name, which seems to be in conflict
with --userns and requires manual mapping of uid and gid, which is not
what I want.
Running podman-compose --in-pod=false up leads to a successful run. To make this
the default for this project, I can add the following snippet to the
docker-compose.yml according to this Github comment
x-podman:
in_pod: false
Conclusion
With this solved and immediately put to use by writing this blog post, I can now continue playing around with Podman and getting more comfortable with its way of handling containers, as I’m interested in running containers rootless in my small homelab.