Docker挂载CIFS共享导致权限问题

205次阅读
没有评论

问题描述

在一个只有20GB SSD的小型虚拟机上运行Docker,这足够存放操作系统、交换空间、Docker和容器镜像。但现在他想在该主机上运行一个Nextcloud Docker镜像。由于空间不足,他将一个CIFS共享挂载到了/data目录,并将Nextcloud的数据目录链接到了该共享上。

docker run -v /data/docker-volumes/nextcloud/data/:/var/www/html/ -p 8080:80 nextcloud

文件已经创建,但是Docker尝试将文件的所有权更改为www-data,但由于目标系统(SMB服务器)上不存在www-data用户,所以失败并终止了Docker实例。

rsync: chown "/var/www/html/data" failed: Permission denied (13)rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]

在目标系统上无法创建www-data用户。有没有办法解决这个问题?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

可以通过使用挂载选项来强制应用正确的用户和组,即使这些属性在目标系统上无法设置,也足以解决与Docker相关的问题。此外,还需要定义一组合理的权限,用于新文件和文件夹。
以下是使用mount命令挂载CIFS共享的示例:

mount -t cifs -o username=user,password=pass, \
               # 提供凭据
  uid=www-data,forceuid,gid=root,forcegid, \
               # 强制指定gid和uid
  file_mode=744,dir_mode=744 //host/share /local/mountpoint
               # 设置新文件和目录的权限

在上面的示例中,我们使用mount命令挂载了一个CIFS共享。通过-o选项提供了用户名和密码,uidgid选项强制指定了www-dataroot的用户和组。file_modedir_mode选项设置了新文件和目录的权限。
请注意,具体的挂载选项可能因系统和环境而异,你需要根据自己的情况进行调整。

方案2

使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。

示例:

以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:

#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b

在这个示例中,我们首先使用docker run命令启动容器A,并将其命名为container_a。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo命令来测试)。一旦容器A就绪,我们再使用docker run命令启动容器B,并将其命名为container_b

以上是解决Docker挂载CIFS共享导致权限问题的两种方案。你可以根据自己的需求选择适合的方法。

正文完