在Docker容器内运行 `mkdir` 时出现“Permission denied”错误

5
我正在使用Docker Compose来运行几个容器,其中包括一个Postgres镜像的容器。我试图向该容器添加卷来保持容器构建之间的数据一致性。但是,当它尝试在容器内创建此卷的目录时,我收到了一个错误。
我运行: docker-compose build 然后 docker-compose up 然后我收到以下错误:
ERROR: for cxbenchmark_db_1 Cannot start service db: oci runtime error: container_linux.go:265: starting container process caused "process_linux.go:368: container init caused \"rootfs_linux.go:57: mounting \\"/var/lib/docker/volumes/69845a017b4465e9122852a75ca194db473df95fa218658b8a60fb56eba9be9e/_data\\" to rootfs \\"/var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged\\" at \\"/var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged/var/lib/postgresql/data\\" caused \\"mkdir /var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged/var/lib/postgresql/data: permission denied\\"\""
我的完整的docker-compose.yml文件如下(请注意定义了卷的服务名为db):
version: '3'  

services:  
  nginx:
    image: nginx:latest
    ports:
      - 80:8000
    volumes:
      - ./src:/src
      - ./config/nginx:/etc/nginx/conf.d
      - ./src/static:/static
    depends_on:
      - web

  web:
    build: .
    command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn cx_benchmark.wsgi -b 0.0.0.0:8000"
    depends_on:
      - db
    volumes:
      - ./src:/src
      - ./src/static:/static
    expose:
      - 8000

  db:
    image: postgres:latest
    volumes:
      - /private/var/lib/postgresql:/var/lib/postgresql
    ports:
      - 5432:5432

有解决的想法吗?

(关于IT技术)
1个回答

7
您看到的错误与您compose文件中的显式卷绑定无关,而是与主postgres官方Docker镜像Dockerfile中的VOLUME声明有关:

VOLUME /var/lib/postgresql/data

由于您没有为此目录提供挂载点(而是父目录),因此docker引擎正在创建一个本地卷,然后尝试将该卷挂载到您已经绑定的位置,并出现权限错误。

为了明确起见,这是docker引擎为您创建的卷:

/var/lib/docker/volumes/69845a017b4465e9122852a75ca194db473df95fa218658b8a60fb56eba9be9e/_data

以下是它尝试绑定挂载该目录的位置;在您的绑定挂载/private/var/lib/postgresql之上:

mkdir /var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged/var/lib/postgresql/data: permission denied

现在,我认为这个失败的原因可能是您在Docker引擎中启用了用户命名空间(“userns-remap”标志/设置),以至于容器没有权限在主机上的该根拥有位置创建目录。除此之外,唯一的其他选择是postgres容器作为非root用户启动,但我在您的compose文件或最新发布的Dockerfile中没有看到使用USER指令的任何内容。
顺便说一句,由于您的绑定挂载与postgres Dockerfile中的VOLUME限定符不匹配,因此您最终会获得双卷,您可以将您的compose文件更改为挂载到/var/lib/postgresql/data,并解决额外创建的那个卷问题。特别是如果您希望您的DB数据最终出现在/private/var/lib/postgresql中,因为它可能会让人惊讶地发现它不在那里,而是在/var/lib/docker/volumes/..位置。

谢谢您的见解!我绝对不想要那些双卷。我已经在我的docker-compose文件的数据库服务中更改了卷条目如下:/private/var/lib/postgresql/data:/var/lib/postgresql/data但是现在,当postgres容器尝试更改该目录的权限时,我遇到了以下错误:db_1 | chown: changing ownership of '/var/lib/postgresql/data': Operation not permitted您有什么解决方法吗? - zhirsch
1
是的,因此官方镜像的入口脚本也尝试对数据目录进行“chown”操作,现在正在尝试更改主机挂载目录的所有权。这就是为什么我很好奇您的Docker引擎是否启用了用户命名空间,因为通常此操作将适用于“root”用户。但是,上面显示的路径/var/lib/docker让我觉得情况并非如此。/private/var/lib/postgresql/data的权限位是什么,谁拥有它?这个示例使用的是“Docker for Mac”吗? - Phil E
谢谢@PhilE。我也遇到了完全相同的问题,苦苦挣扎了几周。你的解决方案完美地解决了我的问题。 :) - Ibrahim
1
@PhilE 这个问题有人解决了吗? 我也遇到同样的问题。 我们可以更改Docker引擎用户吗?更改标志对我没有起作用。 我在macOS上。 - informer
我想这给了我一些见解,但我还是卡住了;我似乎找不到一个真正的解决方案。 - Stephan Henningsen
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接