wan*_*ars 16 linux scripting docker
我有一个OpenSuse 42.3 docker镜像,我已配置为运行代码.该图像有一个名为"myuser"的用户(除了root用户),我是在通过Dockerfile生成初始图像时创建的.我有三个脚本文件,根据用户所使用的操作系统从映像生成容器.
问题:容器中的用户名"myuser"是否可以设置为执行容器生成脚本的用户的用户名?
我的目标是让用户以交互方式弹出容器,并能够从容器中运行代码.代码只是一个执行并具有一些IO的二进制文件,因此我希望可以从容器中访问用户的目录,以便它们可以导航到其计算机上的文件夹并运行代码以在其文件系统中生成输出.
以下是我到目前为止构建的内容.我尝试在linux脚本调用期间设置USER环境变量docker run,但这并未将用户从"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 \
Run Code Online (Sandbox Code Playgroud)
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 \
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)
以下代码已签入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 "$@"
Run Code Online (Sandbox Code Playgroud)
以下是相关 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
Run Code Online (Sandbox Code Playgroud)
然后要运行它,您只需将 /home/myuser 作为卷挂载,它将调整入口点中的权限。例如:
$ docker build -t run-as-user .
$ docker run -it --rm -v $(pwd):/home/myuser run-as-user /bin/bash
Run Code Online (Sandbox Code Playgroud)
在该容器内,您可以运行id并ls -l查看是否有权访问 /home/myuser 文件。