Dockerfile 将主机用户 UID 和 GID 复制到镜像
Posted
技术标签:
【中文标题】Dockerfile 将主机用户 UID 和 GID 复制到镜像【英文标题】:Dockerfile replicate the host user UID and GID to the image 【发布时间】:2017-11-24 18:31:55 【问题描述】:类似于SO post about replicating UID/GID in container from host,但是如何使用具有复制 UID 和 GID 的用户构建映像?最好,你如何使用 dockerfile 来做这件事?
我可以使用 bash 脚本来完成:
#!/bin/bash
# current uid and gid
curr_uid=`id -u`
curr_gid=`id -g`
# create bb.dockerfile:
cat << EOF1 > bb.dockerfile
FROM ubuntu:xenial-20170214
ARG UNAME=testuser
EOF1
echo ARG UID=$curr_uid >> bb.dockerfile
echo ARG GID=$curr_gid >> bb.dockerfile
cat << EOF2 >> bb.dockerfile
RUN groupadd -g \$GID \$UNAME
RUN useradd -m -u \$UID -g \$GID -s /bin/bash \$UNAME
USER \$UNAME
CMD /bin/bash
EOF2
docker build -f bb.dockerfile -t testimg .
这个 bash 将生成一个如下所示的 docker 文件并在其上构建。
FROM ubuntu:xenial-20170214
ARG UNAME=testuser
ARG UID=1982
ARG GID=1982
RUN groupadd -g $GID $UNAME
RUN useradd -m -u $UID -g $GID -s /bin/bash $UNAME
USER $UNAME
CMD /bin/bash
我要的是从 dockerfile 中删除硬编码的主机 UID 1982 和 GID 1982。
【问题讨论】:
【参考方案1】:您可以将其作为构建参数传递。你的 Dockerfile 可以是静态的:
FROM ubuntu:xenial-20170214
ARG UNAME=testuser
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID -o $UNAME
RUN useradd -m -u $UID -g $GID -o -s /bin/bash $UNAME
USER $UNAME
CMD /bin/bash
然后您将在构建命令中传递选项:
docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) \
-f bb.dockerfile -t testimg .
请注意,我已经以不同的方式解决了与此类似的问题,方法是以 root 身份运行一个入口点,该入口点查看主机卷挂载的文件/目录权限,并调整容器内用户的 uid/gid 以匹配卷 uid/gid。进行该更改后,它会放弃从 root 用户到修改后的 uid/gid 用户的访问权限,并运行原始命令/入口点。结果是图像可以在任何开发人员机器上不变地运行。这方面的一个例子可以在我的 jenkins-docker repo 中找到:
https://github.com/sudo-bmitch/jenkins-docker
【讨论】:
我不明白,命令行中的 UID 和 GID 参数是否会隐藏/覆盖“静态”Dockerfile 条目? 在我的 docker 容器 ubuntu guest 中,gid 20 属于拨出。通常应该为您在主机上的用户帐户分配其自己的组 id,而不是重复使用 20。如果您运行id -g
,您会得到 20 吗? id -u
得到什么?
@AlexanderMills 我猜你可能在 guid 20 = 员工的 macos 上运行,但来宾是一些 20 = 其他东西的 linux。这种传递组 ID 并创建组的想法似乎只有在组不存在时才有意义,这在 linux 主机上就是这种情况,通常您的 GID 将是一个只包含您自己的组。
@AlexanderMills 是的,dockerfile 中 docker args 的默认值会被 build 命令覆盖。如果容器中已经存在 uid/gid,您可以添加 -o
选项以允许非唯一 id。
干净的答案,它解决了 docker 的很多问题。尤其是在使用 jenkins 启动 docker 时..【参考方案2】:
最终bb.bash
看起来像:
#!/bin/bash
# current uid and gid
curr_uid=`id -u`
curr_gid=`id -g`
# create bb.dockerfile:
cat << EOF2 > bb.dockerfile
FROM ubuntu:xenial-20180417
ARG UNAME=testuser
ARG UID=1000
ARG GID=1000
RUN groupadd -g \$GID \$UNAME
RUN useradd -m -u \$UID -g \$GID -s /bin/bash \$UNAME
USER \$UNAME
CMD /bin/bash
EOF2
docker build --build-arg UID=$curr_uid --build-arg GID=$curr_gid \
-f bb.dockerfile -t testimg .
然后另一个脚本是创建容器:
#!/bin/bash
docker run -it -d -v $(pwd)/shared:/home/testuser/shared \
--name testcontainer -P testimg
【讨论】:
还创建了一个 docker 文件和脚本以通过 ssh 运行 X:参见 superuser SO "Run JetPack TX2 Installer in a Docker Container"。以上是关于Dockerfile 将主机用户 UID 和 GID 复制到镜像的主要内容,如果未能解决你的问题,请参考以下文章