【docker】 bind-mount或者COPY时需要注意 用户、文件权限 的问题
【docker】 bind-mount或者COPY时需要注意 用户、文件权限 的问题
问题产生原因
如果没有时间查看下面的最佳解决方案,可以试试这个简单粗暴的解决方案:在 宿主机器上,通过 sudo chmod -R 777 /path/to/dir
将 被挂载的目录的权限比特位设为777。这样,这个目录就能被任何用户读写,包括【docker容器主进程的owner】。但是这个方法可能会造成安全隐患,另外,git会将权限改动也视为文件变动(需要 设置一下git来解决)。
实例:判断问题
查看宿主上的权限信息
查看容器内的权限信息
docker exec -it container_name /bin/bash
你可以验证一下被bind-mount、COPY的文件,它们的权限信息是否与宿主上的相同:权限比特位、owner ID、group ID。
从上图可以看到,主进程的拥有者是
root
,root可以读写任何文件,权限肯定没问题。但是主进程还创建了两个子进程,拥有者是www-data
,这个用户有可能无法读写【被bind-mount或者COPY到容器内的文件】!因此,现在我们需要检查
www-data
是否存在权限不足的问题,首先通过id username
来查看这个用户的 user id、primary group id、加入的所有群组 的信息:然后,使用
stat
或者ls -na
命令,查看【被bind-mount或者COPY到容器内的文件】的权限信息:上图的
/codeigniter
文件夹是我通过bind-mount挂载到容器内的。可以看到这个文件夹以及其中的文件的ownerId:groupId
都是1000:1000
,而www-data
的ownerId:groupId
是33:33
。再结合这些文件的权限信息(比如-rw-rw-r--
、drwx------
),www-data
只能读取其中一些文件,无法写入任何文件,/codeigniter/application/
这个文件夹内的内容连访问都不行!如上图,用
stat
也能看到同样的文件信息,只不过一次只能看到一个文件或文件夹的信息。
【容器主进程】有可能会创建其他的进程一起工作(比如上面的例子),如果是这样的话,你需要检查所有子进程都有权访问自己所需的文件。
实例:解决问题
改变
www-data
的uid和gid,从33:33
变成1000:1000
。这样www-data
就是这些文件的owner了,自然就有需要的权限了。改变uid和gid可以通过我上篇文章介绍的usermod
命令。具体来说,就是在Dockerfile中加入这样一句:RUN usermod -u 1000 www-data && usermod -G 1000 www-data
。(其实不需要改gid的,改uid就可以成为owner了)通过
chmod
命令,在宿主机器上改变codeigniter
文件夹的权限比特为777。这样,在bind-mount到容器里面以后它的权限也是777,因此任何用户都可以读写它的内容。这个方法要求修改开发环境,不太优雅。实际上
COPY --chown=www-data:www-data ./codeigniter /codeigniter/
就能一步将【被COPY的文件】的owner设置为容器内的某个用户。