问题描述
在一个只有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
选项提供了用户名和密码,uid
和gid
选项强制指定了www-data
和root
的用户和组。file_mode
和dir_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共享导致权限问题的两种方案。你可以根据自己的需求选择适合的方法。