繁体   English   中英

添加卷到 Docker,但排除子文件夹

[英]Add a volume to Docker, but exclude a sub-folder

假设我的主机/hostFolder上有一个 Docker 容器和一个文件夹。 现在,如果我想将此文件夹作为卷添加到 Docker 容器中,那么我可以通过在Dockerfile中使用ADD或将其作为卷安装来执行此操作。

到目前为止,一切都很好。

现在/hostFolder包含一个子文件夹/hostFolder/subFolder

我想将/hostFolder挂载到 Docker 容器中(无论是读写还是只读都无关紧要,对我来说都适用),但我不想将它包含在 / hostFolder /hostFolder/subFolder中。 我想排除这一点,我还希望 Docker 容器能够对此子文件夹进行更改,而不会在主机上也发生更改。

这可能吗? 如果是这样,如何?

使用 docker-compose 我可以在本地使用 node_modules,但在docker-compose.yml中使用以下语法在docker-compose.yml容器中忽略它

volumes:
   - './angularApp:/opt/app'
   - /opt/app/node_modules/

所以./angularApp所有./angularApp都映射到/opt/app然后我创建另一个挂载卷/opt/app/node_modules/现在是空目录 - 即使在我的本地机器中./angularApp/node_modules不是空的。

如果你想让docker-compose.yml -compose 忽略子目录但持久化,你可以在docker-compose.yml执行以下docker-compose.yml

volumes:
  node_modules:
services:
  server:
    volumes:
      - .:/app
      - node_modules:/app/node_modules

这会将您的当前目录挂载为共享卷,但会挂载一个持久的node_modules卷来代替您的本地node_modules目录。 这类似于@kernix 的答案,但这将允许node_modulesnode_modules docker-compose up运行之间保持node_modules ,这可能是所需的行为。

要排除文件,请使用以下命令

volumes:
   - /hostFolder:/folder
   - /dev/null:/folder/fileToBeExcluded

对于那些试图在node_modules不被本地覆盖的情况下获得良好工作流程的人来说,这可能会有所帮助。

  1. 更改您的 docker-compose 以将匿名持久卷安装到 node_modules 以防止您的本地覆盖它。 这已在此线程中概述了几次。
services:
  server:
    build: .
    volumes:
      - .:/app
      - /app/node_modules
  1. 这是我们遗漏的重要一点。 旋转堆栈时,请使用docker-compose -V 如果没有这个,如果你添加了一个新包并重建了你的镜像,它将使用你最初的node_modules -compose 启动中的node_modules
    -V, --renew-anon-volumes   Recreate anonymous volumes instead of retrieving
                               data from the previous containers.

首先,在 Dockerfile 中使用ADD指令与使用卷非常不同(通过 docker docker run-v参数或 Dockerfile 中的VOLUME指令)。 ADDCOPY命令只是在运行docker build时获取文件的副本。 在使用docker build命令创建新映像之前,不会更新这些文件。 相比之下,使用卷本质上是说“这个目录不应该存储在容器镜像中;而是使用主机上的目录”; 每当卷中的文件发生更改时,主机和容器都会立即看到它。

我不相信你可以使用卷来实现你想要的,如果你想这样做,你必须重新考虑你的目录结构。

但是,使用COPY (它应该比ADDADD )实现起来非常简单。 您可以使用.dockerignore文件来排除子目录,也可以COPY所有文件,然后执行RUN rm bla删除子目录。

请记住,您使用COPYADD添加到图像的任何文件都必须在构建上下文内,即在您运行docker build的目录中或下方。

使用 docker 命令行:

docker run \
    --mount type=bind,src=/hostFolder,dst=/containerFolder \
    --mount type=volume,dst=/containerFolder/subFolder \
    ...other-args...

也可以使用-v选项(归功于Bogdan Mart ),但--mount更清晰, 推荐使用

对于那些也有 node_modules 文件夹仍会从本地系统覆盖的问题的人,反之亦然

volumes:
  node_modules:
services:
  server:
    volumes:
      - .:/app
      - node_modules:/app/node_modules/

这是解决方案,在 node_modules 之后的尾随/是修复。

看起来旧的解决方案不再适用(至少对我而言)。 不过,创建一个空文件夹并将目标文件夹映射到它有帮助。

volumes:
   - ./angularApp:/opt/app
   - .empty:/opt/app/node_modules/

我发现这个链接救了我: Working with docker bind mounts and node_modules
此工作解决方案将在 docker 卷管理器中创建一个“排除”命名卷。 卷名称“exclude”是任意的,因此您可以为卷使用自定义名称 intead exclude

services:
    node:
        command: nodemon index.js
        volumes:
            - ./:/usr/local/app/
            # the volume above prevents our host system's node_modules to be mounted
            - exclude:/usr/local/app/node_modules/

volumes:
    exclude:

您可以在官方文档中查看有关卷的更多信息 - Use a volume with docker compose

要排除包含在您机器的卷中的已挂载文件,您必须通过为该文件分配一个卷来覆盖它。 在您的配置文件中:

services:
  server:
    build : ./Dockerfile
    volumes:
      - .:/app

dockerfile 中的一个示例:

# Image Location
FROM node:13.12.0-buster
VOLUME /app/you_overwrite_file

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM