假设我有一个Docker容器和一个文件夹在我的主机/hostFolder。现在,如果我想将这个文件夹作为卷添加到Docker容器中,那么我可以通过在Dockerfile中使用add或将其作为卷挂载来做到这一点。

到目前为止,一切顺利。

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

我想把/hostFolder挂载到Docker容器中(无论是读写还是只读都不重要,对我来说都适用),但我不想把它包括在/hostFolder/subFolder中。我想排除这个,我还希望Docker容器能够对这个子文件夹进行更改,而不需要在主机上更改它。

这可能吗?如果有,怎么做?


First, using the ADD instruction in a Dockerfile is very different from using a volume (either via the -v argument to docker run or the VOLUME instruction in a Dockerfile). The ADD and COPY commands just take a copy of the files at the time docker build is run. These files are not updated until a fresh image is created with the docker build command. By contrast, using a volume is essentially saying "this directory should not be stored in the container image; instead use a directory on the host"; whenever a file inside a volume is changed, both the host and container will see it immediately.

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

但是,使用COPY(应该优先使用ADD)实现它非常简单。您可以使用.dockerignore文件来排除子目录,或者您可以复制所有文件,然后执行RUN rm bla来删除子目录。

记住,你使用COPY或add添加到image的任何文件必须在build上下文中,即在你运行docker build的目录中或下面。


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

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

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


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

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

这将把您的当前目录挂载为共享卷,但是在本地node_modules目录的位置挂载一个持久的docker卷。这与@kernix的回答类似,但这将允许node_modules在docker-compose up运行之间持续存在,这可能是理想的行为。


要排除一个文件,请使用以下方法

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

看起来旧的解决方案已经不管用了(至少对我来说)。 创建一个空文件夹并将目标文件夹映射到它会有所帮助。

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

使用docker命令行:

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

-v选项也可以使用(credit to Bogdan Mart),但——mount更清晰,建议使用。


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

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

这是解决方案,node_modules后面的/是修复。


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

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

你dockerfile中的一个例子:

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

对于那些试图在node_modules不被local覆盖的地方获得一个良好的工作流的人来说,这可能会有所帮助。

更改docker-compose,将匿名持久卷挂载到node_modules,以防止本地覆盖它。在这篇文章中已经概述了几次。

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

这是我们忽略的重要部分。当旋转堆栈时,使用docker-compose -V。如果没有这一点,如果您添加了一个新包并重新构建映像,那么它将使用初始docker-compose启动时的node_modules。

    -V, --renew-anon-volumes   Recreate anonymous volumes instead of retrieving
                               data from the previous containers.

我发现这个链接拯救了我:使用docker绑定挂载和node_modules。 这个工作解决方案将在docker卷管理器中创建一个名为volume的“排除”。卷名“exclude”是任意的,因此可以为卷使用自定义名称而不是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:

你可以在官方文档中看到更多关于卷的信息-使用docker合成卷