- 作者:
- 分类:知识&开发->工具->容器&虚拟机
- 阅读:3213
- 点赞:5
- 版权:CC BY-SA 4.0
- 创建:2020-05-15
- 更新:2023-12-19
原文链接(持续更新):https://neucrack.com/p/285
参考这里的三种方法: Avoiding Permission Issues With Docker-Created Files
但是这三种方法都有缺陷,
第二种简单方便,官方也推荐,但是当运行一些软件就会出现问题,因为没有root权限,在创建文件时就会出错了;
最后一种看起来最好,但是用户需要在 build 的时候指定,而不是在创建容器的时候指定,不是很方便
想要在创建容器的时候指定用户,可以:
传入环境变量 NEW_USER_NAME
NEW_USER_ID
NEW_GROUP_ID
Dockerfile 给容器添加一个CMD,判断是否有这个用户,没有就创建用户及组,并把用户加到这个组里面
groupadd --gid $NEW_GROUP_ID $NEW_USER_NAME
adduser --disabled-password --gecos "" --uid $NEW_USER_ID --gid $NEW_GROUP_ID $NEW_USER_NAME
su $NEW_USER_NAME
然后切换到新的用户使用容器即可,这样在容器中创建的文件在宿主机中就不是属于 root 组 和 root 用户的了,而是属于宿主机的当前用户
为了让新用户的终端中能显示中文,在~./.bashrc
设置LANG
变量
echo "export LC_ALL=C.UTF-8" >> /home/$USER_NAME/.bashrc
echo "export LANG=C.UTF-8" >> /home/$USER_NAME/.bashrc
另外,在使用新的用户启动 jupyterlab 时,遇到了语言环境问题,没法显示中文
使用了
su - $USER_NAME -c "jupyter-lab --ip=0.0.0.0 --port=8889 --no-browser --notebook-dir=${NOTE_ROOT}"
运行时指定环境变量
su - ${USER_NAME} -c "LANG=C.UTF-8 LC_ALL=C.UTF-8 jupyter-lab --ip=0.0.0.0 --port=8889 --no-browser --notebook-dir=${NOTE_ROOT}"
或者这样也行
su - ${USER_NAME} <<EOF
export LANG=C.UTF-8
export LC_ALL=C.UTF-8
jupyter-lab --ip=0.0.0.0 --port=8889 --no-browser --notebook-dir=${NOTE_ROOT}
EOF # 这里必须在行首不能有空格
可以参考我设置的 jupyterlab 的 Dockerfile : https://github.com/Neutree/dockerfiles/tree/master/tensorflow_gpu_py3_jupyterlab
另外,在需要root权限时,可以使用如下命令使用root用户进入容器
docker exec -it 容器名或ID /bin/bash
如果需要用户直接在jupyter里面可以使用root权限,直接使用su root
默认是无法使用的,默认没有root密码,可以使用上面的命令进入容器设置一个root密码,或者在dockerfile里面设置一个默认密码;
或者可以将用户加入到root组并且安装sudo
工具
apt install sudo
usermod -g root 用户名
编辑/etc/sudoers
%root ALL=(ALL:ALL) ALL
这一步也可以在上面的创建容器的时候做
举例
Dockerfile
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND noninteractive
# RUN dpkg --add-architecture i386 \
# && apt-get -o APT::Retries=3 update -y
# RUN apt-get update \
# && apt-get install build-essential vim \
# git libncurses5-dev zlib1g-dev gawk \
# libssl-dev unzip lib32z1 lib32z1-dev lib32stdc++6 libstdc++6 \
# ca-certificates file g++-multilib libc6:i386 locales \
# python3 python3-pip rsync shellcheck \
# libopencv-dev libopencv-contrib-dev \
# unzip wget sudo -y \
# && apt-get purge -yq \
# && apt-get autoremove -yq --purge \
# && apt-get clean \
# && rm -rf /var/lib/apt/lists/* \
# && rm -rf /tmp/*
# RUN python3 -m pip install maixtool cmake
COPY switch_user.sh /usr/local/bin/switch_user.sh
RUN chmod +x /usr/local/bin/switch_user.sh
ENTRYPOINT ["/usr/local/bin/switch_user.sh"]
switch_user.sh
#!/bin/bash
set -e
UID=${UID:-""}
GID=${GID:-""}
USER=${USER:-""}
if [ -z "$USER" ]; then
echo "USER env is required by --env USER=\$USER"
exit 1
fi
if [ -z "$UID" ]; then
echo "UID env is required by --env UID=\`id -u\`"
exit 1
fi
if [ -z "$GID" ]; then
echo "GID env is required by --env GID=\`id -g\`"
exit 1
fi
# if group $USER not exists, add group
if ! grep -q "^$USER:" /etc/group; then
addgroup --gid "$GID" "$USER"
fi
# if user $UID not exists, add user
if ! grep -q "^$USER:" /etc/passwd; then
adduser --gecos "" --uid "$UID" --gid "$GID" --no-create-home --disabled-password "$USER"
mkdir -p /home/"$USER"
cp -r /etc/skel/. /home/"$USER"
# default password is maixcdk
echo "$USER:maixcdk" | chpasswd
usermod -aG sudo "$USER"
fi
chown "$UID":"$GID" /home/"$USER"
su "$USER"
run:
docker build --network=host -t maixcdk-builder .
docker run -it --name maixcdk-env --env USER=$USER --env UID=`id -u` --env GID=`id -g` -v /home/${USER}/MaixCDK:/MaixCDK maixcdk-builder