我有一个OpenSuse 42.3 docker镜像,我已将其配置为运行代码。该图像具有一个名为" myuser"的用户(除root之外)。我在通过Dockerfile生成初始图像期间创建的。我有三个脚本文件,根据用户所使用的操作系统从映像生成容器。
问题:用户名" myuser"在容器中设置为执行容器生成脚本的用户的用户名?
我的目标是让用户以交互方式弹出容器,并能够从容器中运行代码。代码只是一个执行并具有一些IO的二进制文件,因此我希望可以从容器中访问用户的目录,以便他们可以导航到其计算机上的文件夹并运行代码以生成输出他们的文件系统。
以下是我迄今为止所构建的内容。我尝试在linux脚本调用docker run
期间设置USER环境变量,但这并没有改变用户来自" myuser"说" bob" (启动容器的主机上的用户名)。安装目录似乎工作正常。我不确定是否有可能实现我的目标。
Linux容器脚本:
username="$USER"
userID="$(id -u)"
groupID="$(id -g)"
home="${1:-$HOME}"
imageName="myImage:ImageTag"
containerName="version1Image"
docker run -it -d --name ${containerName} -u $userID:$groupID \
-e USER=${username} --workdir="/home/myuser" \
--volume="${home}:/home/myuser" ${imageName} /bin/bash \
Mac容器脚本:
username="$USER"
userID="$(id -u)"
groupID="$(id -g)"
home="${1:-$HOME}"
imageName="myImage:ImageTag"
containerName="version1Image"
docker run -it -d --name ${containerName} \
--workdir="/home/myuser" \
--v="${home}:/home/myuser" ${imageName} /bin/bash \
Windows容器脚本:
ECHO OFF
SET imageName="myImage:ImageTag"
SET containerName="version1Image"
docker run -it -d --name %containerName% --workdir="/home/myuser" -v="%USERPROFILE%:/home/myuser" %imageName% /bin/bash
echo "Container %containerName% was created."
echo "Run the ./startWindowsLociStream script to launch container"
答案 0 :(得分:3)
用户名并不重要。重要的是uid和gid值。
容器内的用户myuser将具有1000的uid(第一个非root用户ID)。因此,当您启动容器并从主机查看容器进程时,您将看到容器由主机上具有uid 1000的任何用户拥有。
您可以使用以下命令运行容器时指定用户来覆盖此项:
docker run --user 1001 ...
因此,如果您希望容器内的用户能够访问拥有1005 uid的用户拥有的主机上的文件,请使用--user 1005运行容器。
为了更好地了解用户如何在容器和主机之间进行映射,请查看这篇精彩的文章。 https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf
答案 1 :(得分:2)
以下代码已经检入https://github.com/bmitch3020/run-as-user。
我会在entrypoint.sh中处理这个问题,它会检查/ home / myuser的所有权并更新容器内用户的uid / gid。它看起来像:
#!/bin/sh
set -x
# get uid/gid
USER_UID=`ls -nd /home/myuser | cut -f3 -d' '`
USER_GID=`ls -nd /home/myuser | cut -f4 -d' '`
# get the current uid/gid of myuser
CUR_UID=`getent passwd myuser | cut -f3 -d: || true`
CUR_GID=`getent group myuser | cut -f3 -d: || true`
# if they don't match, adjust
if [ ! -z "$USER_GID" -a "$USER_GID" != "$CUR_GID" ]; then
groupmod -g ${USER_GID} myuser
fi
if [ ! -z "$USER_UID" -a "$USER_UID" != "$CUR_UID" ]; then
usermod -u ${USER_UID} myuser
# fix other permissions
find / -uid ${CUR_UID} -mount -exec chown ${USER_UID}.${USER_GID} {} \;
fi
# drop access to myuser and run cmd
exec gosu myuser "$@"
以下是来自相关Dockerfile的一些行:
FROM debian:9
ARG GOSU_VERSION=1.10
# run as root, let the entrypoint drop back to myuser
USER root
# install prereq debian packages
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
curl \
vim \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install gosu
RUN dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" \
&& chmod 755 /usr/local/bin/gosu \
&& gosu nobody true
RUN useradd -d /home/myuser -m myuser
WORKDIR /home/myuser
# entrypoint is used to update uid/gid and then run the users command
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD /bin/sh
然后运行它,你只需要将/ home / myuser作为卷挂载,它将调整入口点的权限。 e.g:
$ docker build -t run-as-user .
$ docker run -it --rm -v $(pwd):/home/myuser run-as-user /bin/bash
在该容器中,您可以运行id
和ls -l
,以查看您是否有权访问/ home / myuser文件。
答案 2 :(得分:0)
首先(https://docs.docker.com/engine/reference/builder/#arg):
警告:建议不要使用构建时变量进行传递 秘密,如github密钥,用户凭据等。构建时变量 具有泊坞窗历史记录的图像的任何用户都可以看到这些值 命令。
但如果您仍需要这样做,请阅读https://docs.docker.com/engine/reference/builder/#arg:
Dockerfile可能包含一个或多个ARG指令。例如, 以下是有效的Dockerfile:
FROM busybox ARG user1 ARG buildno ...
和https://docs.docker.com/engine/reference/builder/#user:
USER指令设置用户名(或UID)以及可选的 运行映像时使用的用户组(或GID)以及任何RUN,CMD 和Docker文件中的ENTRYPOINT指令。
USER <user>[:<group>] or USER <UID>[:<GID>]