问题描述
在使用Docker、docker-compose和本地开发时,遇到了一个有趣的问题。他使用了绑定挂载卷,名为www-public,该卷由主机的node用户拥有(他创建了一个node用户并将目录的所有权改为node:node)。容器(官方的node镜像)也是以node用户运行的。在我的node应用程序中的某个时刻,我需要写入这个文件夹,但是我遇到了权限错误。这一开始似乎很奇怪,但是后来我发现,这是有道理的,因为我发现,我的主机node用户的uid是1001,而我的容器node用户的id是1000。如果我只是在我的Dockerfile中添加这一行:
RUN usermod -u 1001 node && groupmod -g 1001 node
权限问题就会消失。
我如何解决这个问题,而不是像上面的RUN命令一样硬编码容器node用户id与主机上的node用户id匹配?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在Dockerfile中添加ARG指令,并使用–build-arg选项在docker build命令中传递参数。这样可以在构建镜像时动态设置容器node用户的uid和gid。
以下是具体步骤:
1. 在Dockerfile中添加以下代码:
ARG UID=1000
ARG GID=1000
RUN usermod -u $UID node && groupmod -g $GID node
这里的ARG指令定义了默认值。如果不使用–build-arg选项,则将使用默认值。如果使用了–build-arg选项,则将使用传递的值。
- 使用docker build命令构建镜像,并通过–build-arg选项传递uid和gid参数:
docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) .
这里使用了$(id -u)和$(id -g)命令获取当前用户的uid和gid,并将其传递给–build-arg选项。
方案2
使用docker-compose的user配置项可以指定容器的uid和gid。
以下是具体步骤:
1. 在docker-compose.yml文件中,为服务的配置块添加user配置项:
version: "3"
services:
node-service:
image: node
user: 1001:1001
这将以uid为1001和gid为1001的用户身份运行容器。
请注意,这种方法需要在docker-compose.yml文件中指定uid和gid的值。如果你希望动态设置uid和gid,可以使用方案1中的方法。
以上是两种解决方案,你可以根据自己的需求选择其中一种。