Rootless Podman, volumes and userns mapping

Estimated reading time: 3 minutes

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.