• 8 Posts
  • 18 Comments
Joined 1 year ago
cake
Cake day: June 20th, 2025

help-circle




  • The best way to run Podman is root with UserNS to dole out UID/GID protection. Running Podman as root allows you to share networks between containers while having the containers run under different users. If you go rootless, you’d need to run under one user to share the user’s network space with all the containers you want.

    As for your issue, I can’t really divine what the problem is from the errors. I avoid nginx because it’s coded to not play well with user abstraction and changing the user with the files it wants to write to etc. Gotta write into a ton of random folders! So not sure exactly what is up. But with Podman root it is easy to run as root 0 internally and make nginx think it has all the control it could ever want.

    Try this setup (it is in Podman Quadlet format, apologies I don’t know the compose versions). It runs the container as root 0 internally, externally it runs as some random UID/GID - secure! It uses Volume idmap to map the internal root 0 user to 1001 for write access to the Volume.

    Note that in Debian 13 symlinks are broken and won’t work with idmap, just point to the original source. If you need symlinks, I have an alternate UserNS that maps internal user root 0 to external user 1001 directly. You’d drop the idmap in Volume then and use that. You lose some extra security - now the container is running as external user 1001 instead of some random UID/GID - but that’s a pretty minor hit as long as your external user doesn’t have access to tons of things.

    # Volumes to mount -> the @ is essential for saying "1001 is absolute and external" basically. 0 is internal. size of 1. You can map 1001 to 0 and 1002 to 1 with @1001-0-2, etc., etc., etc.  
    Volume=/mnt/something:/etc/nginx/wants/to/write/here:rw,noexec,nosuid,nodev,Z,idmap=uids=@1001-0-1;gids=@1001-0-1  
    
    # Run as user running the container  
    UserNS=auto  
    # [use this if req symlink b/c idmap does NOT work with symlinks] -> I tested and it is fixed in at least Podman v5.8.3, so Debian 14 will work with idmap and symlinks directly ! drop the idmap if using !  
    # UserNS=auto:uidmapping=0:@1001:1,gidmapping=0:@1001:1  
    
    # Security time  
    NoNewPrivileges=true  
    # https://man7.org/linux/man-pages/man7/capabilities.7.html  
    DropCapability=all  
    ReadOnly=true  
    ReadOnlyTmpfs=True  
    # These capabilities are needed for linuxserver's s6 "launcher" thing  
    #AddCapability=CAP_CHOWN  
    #AddCapability=CAP_DAC_OVERRIDE  
    #AddCapability=CAP_FOWNER  
    #AddCapability=CAP_SETGID  
    #AddCapability=CAP_SETUID  
    # Needs this if the container tries to bind below port 1024. I'm not sure if it is needed if it only tries to bind internally.  
    #AddCapability=CAP_NET_BIND_SERVICE  
    
    # TempFS for ReadOnly fixes I've used for nginx - may not be relevant for you. These are from getting Frigate running.  
    PodmanArgs=--tmpfs /usr/local/nginx/conf:size=1M,rw,noexec,nosuid,nodev  
    PodmanArgs=--tmpfs /usr/local/nginx/logs:size=40M,rw,noexec,nosuid,nodev  
    PodmanArgs=--tmpfs /usr/local/nginx/client_body_temp:size=1M,rw,noexec,nosuid,nodev  
    PodmanArgs=--tmpfs /usr/local/nginx/proxy_temp:size=1M,rw,noexec,nosuid,nodev  
    PodmanArgs=--tmpfs /usr/local/nginx/fastcgi_temp:size=1M,rw,noexec,nosuid,nodev  
    PodmanArgs=--tmpfs /usr/local/nginx/uwsgi_temp:size=1M,rw,noexec,nosuid,nodev  
    PodmanArgs=--tmpfs /usr/local/nginx/scgi_temp:size=1M,rw,noexec,nosuid,nodev  
    PodmanArgs=--tmpfs /etc/letsencrypt:size=1M,rw,noexec,nosuid,nodev  
    

    Root Podman and UserNS=auto needs a containers user to pull uid/gid from.

    # Root Podman needs a `containers` "user" (not really a user, just a reserved uid/gid space)  
    sudo echo "containers:2147483647:2147483648" >> /etc/subuid  
    sudo echo "containers:2147483647:2147483648" >> /etc/subgid  
    

    The documentation for Podman is critically lacking in the “hobbyist” space. Hope this helps.

    Edit: This approach works well because most Docker containers are built assuming they’ll run as root 0. That’s why Linuxserver uses the S6 overlay thing to jump from root 0 to something else. The container can be built to run as any user though, if you look at the Dockerfile for the container you’re using, you’ll see what user they’re declaring it will run as (and likely what user owns all the files). Root 0 usually gets around that problem - unless they “cleverly” code it to try to prevent you from running the container as root 0 (I’ve run into this before! It was Heimdall from the Linuxserver people).

    Edit2: I’ve noticed you said no Volumes, so drop that. But you can still use the UserNS mapping to run it as root internally which should fix the internal permissions issues. The tmpfs stuff is if you declare ReadOnly for extra security - it’s a great idea - but nginx is extra difficult in that regard. Disregard it while you get going.

    # Run as user running the container  
    UserNS=auto  
    
    # Security time  
    NoNewPrivileges=true  
    # https://man7.org/linux/man-pages/man7/capabilities.7.html  
    DropCapability=all  
    # These capabilities are needed for linuxserver's s6 "launcher" thing  
    #AddCapability=CAP_CHOWN  
    #AddCapability=CAP_DAC_OVERRIDE  
    #AddCapability=CAP_FOWNER  
    #AddCapability=CAP_SETGID  
    #AddCapability=CAP_SETUID  
    # Needs this if the container tries to bind below port 1024. I'm not sure if it is needed if it only tries to bind internally.  
    #AddCapability=CAP_NET_BIND_SERVICE  
    

    Edit3:
    Use sudo podman top nginx user huser group hgroup groups hgroups to see the internal user/host user (huser) mappings easily for debug.

    USER	HUSER		GROUP	HGROUP		GROUPS	HGROUPS  
    root		2147485695	root		2147485695	105		105  
    

    Here’s an output from my frigate container. Internally (USER) it is root, externally (HUSER) it’s some random UID. I’ve also mapped the internal group (GROUPS) 105 to the external group (HGROUPS) 105 so that it has render access.















  • Management people like that do deserve your ire. They’re shit people who make it hard for everyone else because they have an extreme authoritarian view of running the corpo and will do what they want at the expense of rationality.

    It’s extra stupid because if someone they need (very specific need for a pet project basically) or someone they know personally comes along - that person would get all accommodations in a heart beat.

    But your team means nothing, the project means nothing (unless it is the pet project of the dipshit who gets to make the decision). They’re a shit person and you can’t change that and it sucks.

    Sorry the inflexibility of dipshit management is hurting you. It happens and it’s their fault, they will cause damage to the corpo, but they’re also probably too weak to tank the whole thing. Just a callous inefficiency. And you can hate them, they deserve it. It’s so easy to see a way towards a solution - but if bozo thinks bozo can get away with burning you to preserve some ephemeral corporate mandate for “in person”, bozo will burn you. The corpo mandate may disappear in a few years, but all that dipshit can do is think short term. And it sucks for you, it suck’s for your coworkers, and again, I’m sorry.

    Be stronk, your labor is your power. You’ll have to leave with your power, and that sucks ass. But your partner will be happy, and that may be worth it to you - especially if this corpo has bozos like that in high places, you’d probably run into something stupid that would be a deal breaker at some point.

    Lastly, no allegiance to the corpo, but your coworkers can be good. They may advocate for you, they may reference for you. Don’t trust anyone or any promises from corpo, including your local manager on up. Ideally that’s not how it should work - talent is talent even if you have to be flexible to keep talent - but corpos are authoritarian by nature and lack guardrails so dipshits get hooked on capricious short-term behaviour.

    Be pissed, fuck em, don’t train your replacement & walk out before that, remember you’re worth keeping in a sane world, because you worth it

    Edit: lastly, don’t dwell on it. Leave the shitstain where it is at your old job, don’t bring it in your mind. That’s really hard because it’s literally one capricious decision causing the issue - but do it for your sake. That’s the cost of living in authoritarian structures, don’t let it eat at you. You worth it, you’ll find something else