How to generate files in a docker container for having the same owner as the host's user

拜拜、爱过 提交于 2020-01-23 16:27:09

问题


I use docker containers to get some development tasks done in my git repositories.

The containers I use are built specifically for each project, that way each contributor only need docker CLI to get things done.

The bad side is the container run as root, thus generated files are owned by root once the container stops, and that's bad..

I can't change the owner in the container before exiting because there isn't the required user in the container /etc/passwd file.

I would create a user in the container before compiling the docker image but then the container won't be universal (for all my dev team).

What is the best practice(s) about that ?


回答1:


A solution is to create a new dockerfile in the repository which is based on the former image (pre-installed with devtools but with no user created but root).

In a such dockerfile, write something like the following:

FROM <ABSTRACT_FORMER_IMAGE>
ARG username=developer
RUN useradd -r -u 1001 -g $username $username
USER $username

Then, before starting to work, each developer in the team should use the dockerfile to build its own base image for new project+developer specific containers, passing its username.

$ docker build --build-arg username=$USER Dockerfile

Some better practices out there ?




回答2:


You can add your user to the image, launch the container as root, and use an entrypoint to adjust the uid/gid inside the container to match that of the volume mounts from your devs. Then switch to your container user to run your app.

To implement this, I've used an entrypoint shell script that includes the following lines:

  OLD_UID=`getent passwd "${opt_u}" | cut -f3 -d:`
  NEW_UID=`ls -nd "$1" | cut -f3 -d' '`
  if [ "$OLD_UID" != "$NEW_UID" ]; then
    usermod -u "$NEW_UID" "$opt_u"
    if [ -n "$opt_r" ]; then
      find / -mount -uid "$OLD_UID" -exec chown "$opt_u" {} \;
    fi
  fi
  OLD_GID=`getent group "${opt_g}" | cut -f3 -d:`
  NEW_GID=`ls -nd "$1" | cut -f4 -d' '`
  if [ "$OLD_GID" != "$NEW_GID" ]; then
    groupmod -g "$NEW_GID" "$opt_g"
    if [ -n "$opt_r" ]; then
      find / -mount -gid "$OLD_GID" -exec chgrp "$opt_g" {} \;
    fi
  fi

In that script, $1 is the volume mount path, opt_u is the username inside the container, opt_g is the group name, and opt_r is a flag to recursively adjust the filesystem inside the container.

At the very end of my entrypoint, I kick off:

exec gosu "${RUN_AS}" "$@"

Which switches to the user $RUN_AS and exec's the command passed to the entrypoint as that user, and as pid 1. Gosu is used to avoid su running as pid 1.

I've posted a similar example of this before with Jenkins as the app inside the container to match the GID of the docker socket. You can find the repo with all the steps here: https://github.com/bmitch3020/jenkins-docker

This has the significant upside of making the image portable to any developer system, and they can run it with the same command. Whatever the permissions are on the filesystem they map into the container from outside become the uid/gid of the user running commands inside the container. There's no need to lookup the local uid/gid on the developer system for your docker run command, or build your image on each developer workstation with unique uid/gid entries. The only downside of this implementation is that docker exec will enter the container as root, since you need to run your entrypoint as root for access to modify users/groups and filesystem ownership.




回答3:


I would recommend you to read this link to have the complete understanding of docker privileges - and for you, the solution would be to run docker using --user command.



来源:https://stackoverflow.com/questions/47644556/how-to-generate-files-in-a-docker-container-for-having-the-same-owner-as-the-hos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!