如何运行docker run
和docker-compose up/run
命令,以使docker内部进程由与本地用户相同的uuid
用户运行?
我需要这样做,以便由“ inside-docker”进程生成的任何文件都将具有本地用户的所有权权限。
使用alpine:3.9容器,将其装入要写入的文件的卷中并创建文件。假设我当前的用户名是user
。
mkdir output_dir #Create an output directory
docker run -it --rm --volume "/path/to/output_dir:/tmp" alpine:3.9 touch /tmp/file.txt
ls -la output_dir/file.txt
将给出输出:
-rw-r--r-- 1 root root 0 Feb 7 19:51 /path/to/output_dir/file.txt
这意味着我需要sudo chown user:user /path/to/output_dir/file.txt
才能以当前用户的身份访问自己的文件系统。
添加一个Docker Entrypoint,它将在容器内创建一个与本地用户相同的uuid
用户,并执行与该用户相同的任何代码。
docker-entrypoint.sh
#!/bin/sh
TEMP_UID="${TEMP_UID:-1000}"
set -ux
useradd -s /bin/false --no-create-home -u ${TEMP_UID} temp
#su-exec is an executable which makes it easy to run a process as a specific user.
exec su-exec temp $@
与此有关的问题是,我将不得不在每个TEMP_UID=<user_id>
命令中将docker run
作为环境变量注入,或者对于每个docker-compose.yml
命令,将其包含在我的docker-compose up/run
文件中。如果Docker
有一个内部变量来跟踪运行它的用户的uuid
,我将使用它。但是我似乎找不到这样的内部变量。
任何帮助将不胜感激!
答案 0 :(得分:1)
我认为答案很简单
docker run --user ${UID} -it --rm --volume "/path/to/output_dir:/tmp" alpine:3.9 touch /tmp/file.txt
请注意,我在您的示例命令中注入了--user ${UID}
。
答案 1 :(得分:1)
许多当前选项需要在容器外部进行更改以传入当前用户,或者依赖于并非在所有环境中都存在的变量。我的首选解决方案是目标是修复已装载卷上的文件许可权,因此,它是使用脚本更改根用户身份以与卷装载用户ID匹配的脚本以root用户身份启动入口点。然后,入口点的末尾使用exec gosu $app_user_name "$@"
启动应用程序,以从根用户切换到在容器内部被修改的应用程序用户。
执行此操作的脚本在我的base image repo中。请注意fix-perms
脚本,其中包括如下两个部分(一个用于uid,另一个用于gid):
# update the uid
if [ -n "$opt_u" ]; then
OLD_UID=$(getent passwd "${opt_u}" | cut -f3 -d:)
NEW_UID=$(stat -c "%u" "$1")
if [ "$OLD_UID" != "$NEW_UID" ]; then
echo "Changing UID of $opt_u from $OLD_UID to $NEW_UID"
usermod -u "$NEW_UID" -o "$opt_u"
if [ -n "$opt_r" ]; then
find / -xdev -user "$OLD_UID" -exec chown -h "$opt_u" {} \;
fi
fi
fi
OLD_UID值来自映像中的用户ID,而NEW_UID值来自卷安装。如果不匹配,则运行usermod
命令,然后运行递归chown
命令以使用旧的uid / gid修复所有文件。
请注意,在生产中,可以对主机上的用户ID进行标准化,如果需要卷,我可以将主机用户ID与映像的ID匹配,从而允许我以该用户而不是root的身份运行入口点。入口点检查当前用户标识,如果不是root用户,则跳过fix-perms
脚本和gosu
命令。