docker-compose:以特定用户身份创建命名卷

标签 docker docker-compose

这是一个最小的docker-compose.yml:

version: "3.6"

services:
  foo:
    user: "${UID}:${GID}"
    image: node:latest
    container_name: foo
    working_dir: /var/www/foo
    volumes:
      - bar:/var/www/foo/bar

volumes:
  bar:

运行docker-compose up后,命名卷将在/var/lib/docker/volumes/project_bar处创建,并且project_bar目录由 root 所有 - 这很好。尽管其中的_data目录root拥有 - 我希望它由特定的非root用户拥有。

例如:

docker-compose run --rm foo sh -c "mkdir bar/foo"

将失败,并显示mkdir:无法创建目录“bar/foo”:权限被拒绝

我的印象是指定 user: "${UID}:${GID}" (注意:uid/gid可供docker使用,在shell中导出)将解决这个问题。显然我错了。

有没有办法让 /var/lib/docker/volumes/project_bar/_data 由特定用户拥有?如果可能的话,不要chown'ing任何东西。并且不涉及 Dockerfile

编辑:澄清一下,我希望容器中的 /var/www/foo/bar 以及 /var/lib/docker/中的等效项卷 由特定用户而非 root 用户拥有。

最佳答案

您要么涉及 Dockerfile,要么需要使用单独的进程设置卷。命名卷将使用镜像的内容进行初始化,包括文件、目录、所有者和权限。当卷为空或不存在时会发生这种情况。

所以你的选择包括:

  • 更新镜像以包含该目录所需的所有权。请注意,如果图像将其定义为卷,则您的更改必须先于该定义。
  • 提前创建一个具有所需所有权的卷并将其安装到容器中
  • 修改容器的入口点以 root 身份运行,修复权限,然后切换到所需的用户(使用 gosu 等)

扩展第二个选项,您可以通过运行临时容器来执行任务来创建具有所需所有权和内容的卷:

docker container run --rm -v bar-data:/data busybox /bin/sh -c \
  "touch /data/.initialized && chown -R ${UID}:${GID} /data"

然后在您的撰写文件中,您可以将该卷声明为外部卷:

version: "3.6"

services:
  foo:
    user: "${UID}:${GID}"
    image: node:latest
    container_name: foo
    working_dir: /var/www/foo
    volumes:
      - bar:/var/www/foo/bar

volumes:
  bar:
    # tell compose this volume is externally created with a different name
    external: true
    name: bar-data

这将创建一个包含单个文件的卷,需要防止 docker 从镜像内容中重新初始化空卷。这也意味着您需要在卷中加载所需的任何数据,否则卷将是空的。将数据复制到卷的常见方法是使用 tar:

tar -cC source_dir . | \
  docker run --rm -i -v foo-data:/target busybox tar -xC /target

关于docker-compose:以特定用户身份创建命名卷,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61250908/

相关文章:

docker - 在开发人员环境中使用 docker 容器进行测试的平台

bash - ECS/Fargate 容器定义命令参数

docker - Nexus Docker Registry - 匿名拉取失败

docker - 在 Docker 容器启动时启动 "roscore"后跟 "rosrun ...."的最佳做法是什么?

node.js - 无法让我的 Node 应用程序使用单独的 docker compose 文件连接到 kafka

docker-compose 在 mongoDB 中创建复制

docker - 如何通过docker-compose传递--device-cgroup-rule?

amazon-web-services - 前端和后端应用程序的 Docker 示例

mongodb - Docker添加其他参数以启动

postgresql - 在 Docker Compose 多容器应用程序中,如何阻止 Postgres 运行之前发出的语句