默认情况下,docker 容器以假 root 运行,容器中新增的文件在宿主机上往往都是 root 用户的,宿主机用户不方便管理。
我们可以在 docker-compose 或者 docker run 时通过环境变量 UID 和 GID 动态传递宿主机用户信息。
然后在 entrypoint 中动态创建用户。
docker-entrypoint.sh 如下:
#!/bin/bash
# 脚本在遇到任何非零(失败)退出状态时立即停止执行
set -e
## 新建 biosmart 用户,通过环境变量 UID & GID 读取宿主机的用户信息
[ ! -d "/biosmart" ] && mkdir /biosmart
groupadd -g $GID biosmart
useradd -u $UID -g $GID -M -d /biosmart -s /bin/bash biosmart
chown biosmart:biosmart /biosmart
usermod -aG sudo biosmart
# 执行 CMD 命令
exec gosu biosmart $@
首先我们将 biosmart 用户的家目录设置在 /biosmart,加个手动检测和创建(虽然这个目录在之前的步骤中大概率会被创建)。
然后我们通过环境变量 UID 和 GID 新建用户组和用户。
新建用户时使用 -M 不要新建家目录,使用 -d 指定家目录,使用 -s 指定 shell 环境。
然后我们将 /biosmart 目录的权限完全移交给 biosmart(之前可能是用 root 创建的)。
然后有需要我们可以给用户 biosmart 赋予 sudo 权限。
最后我们通过 gosu 来切换用户并执行 CMD/command 参数传递的命令。
gosu 是一个轻量级的工具,它允许在 Docker 容器中以指定用户身份运行命令。
与 su 命令不同,gosu 可以避免出现 "cannot set terminal process group" 等终端相关的错误
Usage: gosu
在 Dockerfile 中我们可以依次安装 gosu,设置 entrypoint:
FROM ubuntu:latest
RUN apt-get update && apt-get install -y gosu
WORKDIR /biosmart
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
上面的语句中 WORKDIR /biosmart
会建立 /biosmart 目录,但是是属于 root 的。
启动容器时:
-e UID=$(id -u) -e GID=$(id -g)
传递宿主机的用户信息-v $PWD/home:/biosmart
可以将容器内的整个用户家目录挂到宿主机上
评论区