Share files between host system and docker container using specific UID

前端 未结 4 1104
耶瑟儿~
耶瑟儿~ 2020-12-14 10:08

I\'m trying to share files within a Docker guest using the volume sharing. In order to get the same UID, and therefore interoperability with those files, I would like to cr

相关标签:
4条回答
  • 2020-12-14 10:33

    I slightly modified @ISanych answer:

    #!/usr/bin/env bash
    
    user_exists() {
      id -u $1 > /dev/null 2>&1
    }
    
    group_exists() {
      id -g $1 > /dev/null 2>&1
    }
    
    setuser() {
      if [[ "$#" != 3 ]]; then
        echo "Usage: $0 <path> <user> <group>"
        return
      fi
      local dest_uid=$(stat -c "%u" $1)
      local dest_gid=$(stat -c "%g" $1)
      if user_exists $dest_uid; then
        id -nu $dest_uid
        return
      fi
      local dest_user=$2
      local dest_group=$3
    
      if user_exists $dest_user; then
        userdel $dest_user
      fi
    
      if group_exists $dest_group; then
        groupdel $dest_user
      fi
    
      groupadd -g $dest_gid $dest_group
      useradd -u $dest_uid -g $dest_gid -s $DEFAULT_SHELL -d $DEFAULT_HOME -G root $dest_user
      chown -R $dest_uid:$dest_gid $DEFAULT_HOME
      id -nu $dest_user
    }
    
    REAL_USER=$(setuser $SRC_DIR $DEFAULT_USER $DEFAULT_GROUP)
    

    setuser function accepts user and group names that you want to assign to uid and gid of provided directory. Then if user with such uid exists then it simply returns login corresponding to this uid, otherwise it creates user and group and returns login originally passed to function.

    So you get the login of user that owns destination directory.

    0 讨论(0)
  • 2020-12-14 10:40

    While researching a solution to this problem, I have found the following article to be a great resource: https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf

    In my scripts, the solution boiled down to the following :

    docker run --user $(id -u):$(id -g) -v /hostdirectory:/containerdirectory -v /etc/passwd:/etc/passwd myimage
    

    Of course, id -u can be replaced by other means of retrieving a user's gid, such as stat -c "%u" /somepath

    0 讨论(0)
  • 2020-12-14 10:42

    This is not possible and will probably never be possible because of the design philosophy of keeping builds independent of machines. Issue 6822.

    0 讨论(0)
  • 2020-12-14 10:43

    The environment is not shared, you could use -e, --env options to set env variables in container.

    I usually use this approach when I want to have the same owner of the mapped volume: I check uid & gid of directory in container and then create a corresponding user. Here my script (setuser.sh) which creates a user for a directory:

    #!/bin/bash
    
    setuser() {
      if [ -z "$1" ]; then
        echo "Usage: $0 <path>"
        return
      fi
      CURRENT_UID=`id -u`
      DEST_UID=`stat -c "%u" $1`
      if [ $CURRENT_UID = $DEST_UID ]; then
        return
      fi
      DEST_GID=`stat -c "%g" $1`
      if [ -e /home/$DEST_UID ]; then
        return
      fi
      groupadd -g $DEST_GID $DEST_GID
      useradd -u $DEST_UID -g $DEST_GID $DEST_UID
      mkdir -p /home/$DEST_UID
      chown $DEST_UID:$DEST_GID /home/$DEST_UID
    }
    setuser $1
    

    And this is the wrapper script which runs commands as the user, where the directory with permissions is specified either as $USER_DIR or in /etc/user_dir

    #!/bin/bash
    if [ -z "$USER_DIR" ]; then
      if [ -e /etc/user_dir ]; then
        export USER_DIR=`head -n 1 /etc/user_dir`
      fi
    fi
    if [ -n "$USER_DIR" ]; then
      if [ ! -d "$USER_DIR" ]; then
        echo "Please mount $USER_DIR before running this script"
        exit 1
      fi
      . `dirname $BASH_SOURCE`/setuser.sh $USER_DIR
    fi
    if [ -n "$USER_DIR" ]; then
      cd $USER_DIR
    fi
    if [ -e /etc/user_script ]; then
      . /etc/user_script
    fi
    if [ $CURRENT_UID = $DEST_UID ]; then
      "$@"
    else
      su $DEST_UID -p -c "$@"
    fi
    

    P.S. Alleo suggested different approach: to map users and groups files into container and to specify uid and gid. So your container does not depend on built-in users/groups you could use it without additional scripts.

    0 讨论(0)
提交回复
热议问题