Adapting container user and group IDs to the host


Recommended Posts

Edit Jun26: Added support for umask, created separte USER_ID and GROUP_ID, and split out the remapping function into a new mapids.sh utility

 

When containers write files to volumes shared with the host, we see several problems:

  • Apps run as the "wrong" user, creating files with ownership other than nobody:users
  • Apps run commands like "chown -R nobody:users", but the UID for nobody and the GID for users may not match the host
  • The container's default umask might be different, causing files to be created with unexpected permissions

 

The typical answer is to hard-code the UID, GID, and umask into the Dockerfile. This works, but restricts your containers so that they can only run on a host with that specific UID/GID/umask. For example, unRAID uses 99:100 for nobody:users, and a umask of 0000. Any container that hard-codes 99:100 is going to be problematic for non-unRAID users. See for example:

 

https://github.com/HurricaneHernandez/dockergui/blob/master/files/install/install.sh

 

Generally speaking, the Dockerfiles shouldn't refer to anything about the host.

 

Really what we need is for Docker to transparently remap UIDs and GIDs from the container to the host, so that a write for "nobody" in the container will always have the right UID to correspond to the host's "nobody".

 

Until that feature comes, I implemented helper utilities that can (1) remap IDs for users and groups, and (2) create a user with specific user and group IDs and umask for running the command. The values are specified using container environment variables at run time:

 

-e UMAP=nobody:99:100 -e GMAP=users:100

 

The above says "Update the nobody user to have UID 99 and effective group ID 100", "Update the users group to have ID 100".

 

-e USER_ID=99 -e GROUP_ID=100 -e UMASK=0000

 

These can be baked into our unRAID templates so that users don't have to worry about them.

 

Here's an example of how it would be used in a Dockerfile:

 

# Rev-locking this to ensure reproducible builds
RUN wget -O /files/runas.sh \
  'https://raw.githubusercontent.com/coppit/docker-inotify-command/dd981dc799362d47387da584e1a276bbd1f1bd1b/runas.sh'
RUN chmod +x /files/runas.sh

ADD start.sh /files/start.sh
RUN chmod a+x /files/start.sh

# Run as root by default
ENV USER_ID 0
ENV GROUP_ID 0
ENV UMASK 0000

CMD /files/runas.sh $USER_ID $GROUP_ID $UMASK /files/start.sh

 

Basically the user provides the desired IDs and umask, and "runas.sh" configures the system before exec'ing the command -- in this case /files/start.sh.

 

The above doesn't change the mapping of existing users and groups. Here's an example for that:

 

ENV UMAP ""
ENV GMAP ""

# Quotes are important here
CMD /files/mapids.sh "$UMAP" "$GMAP" && /files/start.sh

 

I've updated my new inotify-command container to use UMAP and GMAP, so that the container can run "newperms" properly: https://registry.hub.docker.com/u/coppit/inotify-command/. One oddity of the way it works is that the users and groups are remapped in the Dockerfile, but the user/group/umask is set later, inside monitor.sh. The reason is that this container can launch multiple commands, and each could have different settings, as specified in the config file.

 

As another example, I'm using runas.sh to ensure that my FileBot container writes files as nobody:users: https://registry.hub.docker.com/u/coppit/filebot/

 

Here's are the scripts:

 

 

I wanted to throw this out there in case anyone else might find it useful. Feedback is welcome!

Link to comment

Default umask could also be set as part of UGID. I just noticed a difference in the permissions for files created by my FileBot container versus what newperms sets...

 

Some containers use cron or upstart or other methods instead of "CMD". I haven't really looked at them to see if runas.sh could easily be incorporated...

Link to comment

This is a great idea!!

 

I visit these forums and use the dockers created here for my Openmediavault system and always have had issues with permissions.

 

I have been able to do find some workarounds for my issues, but this would benefit everybody who would like to use dockers on any platform....it also makes a lot of sense from a security standpoint...

 

I hope more developers integrate this...

 

Thanks a lot!!!

Link to comment

Understood....if that is the way you feel...that is too bad.

 

I love these forums and have used them as a reference for a lot of ideas and projects...I have pointed many people here that wind up switching over to Unraid...At this point it is not feasible for me to do so...but I still like the knowledge here.

 

Link to comment

Understood....if that is the way you feel...that is too bad.

 

I love these forums and have used them as a reference for a lot of ideas and projects...I have pointed many people here that wind up switching over to Unraid...At this point it is not feasible for me to do so...but I still like the knowledge here.

 

lighten up, it was a joke, hence the lol at the end.....

Link to comment

also phusion baseimage already has a setuser script built in for running apps as any user you like...

 

exec /sbin/setuser nobody python /opt/couchpotato/CouchPotato.py --config_file=/config/settings.conf --data_dir=/config/data > /dev/null 2>&1

 

I'm actually using that underneath. The question though is how to get the UIDs and GIDs correct for "nobody". Also setuser doesn't handle the umask.

 

I visit these forums and use the dockers created here for my Openmediavault system and always have had issues with permissions.

 

Yeah, once this seems to be working well, I was planning to hit up some of the image authors to use it. Transmission seems to be giving me problems, for example.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.