Docker:卷安装目录出现 "permission denied" 错误

Docker: Got "permission denied" error at volume mounting directory

我写了一个docker-compose.yml这样的:

version: "3"
services:
  notebook:    
    image: jupyter/datascience-notebook
    
    ports:
      - "8888:8888"
    volumes: 
      - jupyterlabPermanent:/hahaha
    environment:
      JUPYTER_ENABLE_LAB: "yes"
      TZ: "Asia/Tokyo"
    command:
      start-notebook.sh --NotebookApp.token=''
volumes:
  jupyterlabPermanent:

让我说清楚舞台上出现的角色是什么

当我在 \hahaha 目录的 bash 上使用 touch 命令时,我得到 permission denied

# bash command line at \hahaha

(base) jovyan@4bcdaa228d9e:/hahaha$ touch test.txt
touch: cannot touch 'test.txt': Permission denied

因此,容器中完成的每个任务都无法存储在 \hahahajupyterlabPermanent 卷中,这意味着数据保存在此环境中不起作用。

我该如何解决这个问题? 这个我搜了一下,发现需要修改权限的配置,但是没看懂

我在 Windows 10 Home 上使用 Docker Desktop for Windows 和 WSL 2。

您需要对卷进行 root 访问才能更改权限。所以让我们 运行 一个普通的 Ubuntu 容器并安装卷

docker run -it --rm -v jupyterlabPermanent:/hahaha ubuntu

现在我们可以将组所有权更改为 GID 100,这是 jovyan 用户所属的组,并将权限更改为 775,以便组成员可以写入它

chown :100 /hahaha
chmod 775 /hahaha

现在您可以退出 Ubuntu 容器和 运行 jupyter 容器,您应该可以写入卷。

感谢您回答我的问题。主要问题是我不知道Linux系统有“所有者”和“许可”的概念。但是,一个小时的研究和学习让我弄清楚了这里的问题所在。

我的解决方案 1

我的第一个解决方案是在主机控制台上尝试以下命令行:

docker exec -it -u 0 CONATAINER_NAME /bin/bash

添加 -u 选项并指定 0,root 的用户 ID,让您可以像 root 一样深入容器。

我在容器的顶层目录使用ll命令查看,容器顶层目录的文件和文件夹的权限似乎被root支配,并且hahaha 是其中之一。(这意味着 docker-compose.yml 在顶级目录中为卷创建了 hahaha 目录)

(base) jovyan@4bcdaa228d9e:/$ ll
total 64
drwxr-xr-x   1 root root 4096 Jan 26 00:19 ./
drwxr-xr-x   1 root root 4096 Jan 26 00:19 ../
lrwxrwxrwx   1 root root    7 Jan  6 01:47 bin -> usr/bin/
drwxr-xr-x   2 root root 4096 Apr 15  2020 boot/
drwxr-xr-x   5 root root  340 Jan 26 00:19 dev/
-rwxr-xr-x   1 root root    0 Jan 26 00:19 .dockerenv*
drwxr-xr-x   1 root root 4096 Jan 26 00:19 etc/
drwxr-xr-x   2 root root 4096 Jan 27 22:18 hahaha/
drwxr-xr-x   1 root root 4096 Jan 24 20:30 home/
lrwxrwxrwx   1 root root    7 Jan  6 01:47 lib -> usr/lib/
lrwxrwxrwx   1 root root    9 Jan  6 01:47 lib32 -> usr/lib32/
lrwxrwxrwx   1 root root    9 Jan  6 01:47 lib64 -> usr/lib64/
lrwxrwxrwx   1 root root   10 Jan  6 01:47 libx32 -> usr/libx32/
drwxr-xr-x   2 root root 4096 Jan  6 01:47 media/
drwxr-xr-x   2 root root 4096 Jan  6 01:47 mnt/
drwxr-xr-x   1 root root 4096 Jan 25 02:49 opt/
dr-xr-xr-x 217 root root    0 Jan 26 00:19 proc/
drwx------   2 root root 4096 Jan  6 01:50 root/
drwxr-xr-x   5 root root 4096 Jan  6 01:50 run/
lrwxrwxrwx   1 root root    8 Jan  6 01:47 sbin -> usr/sbin/
drwxr-xr-x   2 root root 4096 Jan  6 01:47 srv/
dr-xr-xr-x  11 root root    0 Jan 26 00:19 sys/
drwxrwxrwt   2 root root 4096 Jan  6 01:50 tmp/
drwxr-xr-x   1 root root 4096 Jan  6 01:47 usr/
drwxr-xr-x   1 root root 4096 Jan  6 01:50 var/

因此,jovyan 无权触摸仅由 root 控制的顶级目录 hahaha 中的内容,这是通过潜入容器实现的root.

我的解决方案 2

第二种解决方案是将docker-compose.yml改写如下:

version: "3"
services:
  notebook:    
    image: jupyter/datascience-notebook
    
    ports:
      - "8888:8888"
    volumes: 
      # 
      - jupyterlabPermanent:/home/jovyan/hahaha # before ->  jupyterlabPermanent:/hahaha
    environment:
      JUPYTER_ENABLE_LAB: "yes"
      TZ: "Asia/Tokyo"
    command:
      start-notebook.sh --NotebookApp.token=''
volumes:
  jupyterlabPermanent:

此更改允许 docker-compose 创建容器,因为卷安装目录设置在 /home/jovyan/hahaha/home/jovyan下的文件和文件夹归jovyan所有(而不是root)所以jovyan可以随意触摸/home/jovyan/hahaha的一些文件。 (无需深入容器 root