将卷添加到 Docker,但排除子文件夹
Add a volume to Docker, but exclude a sub-folder
假设我的主机 /hostFolder
上有一个 Docker 容器和一个文件夹。现在,如果我想将此文件夹作为卷添加到 Docker 容器中,那么我可以通过在 Dockerfile
中使用 ADD
或将其作为卷安装来执行此操作。
到目前为止,还不错。
现在 /hostFolder
包含子文件夹 /hostFolder/subFolder
。
我想将 /hostFolder
挂载到 Docker 容器中(无论是读写还是只读都无所谓,对我来说都适用),但我这样做 NOT 想要包含它 /hostFolder/subFolder
。我想排除这一点,我还希望 Docker 容器能够对此子文件夹进行更改,而不会在主机上也进行更改。
这可能吗?如果是,怎么做?
首先,在 Dockerfile 中使用 ADD
指令与使用卷 非常 不同(通过 -v
参数 docker run
或 Dockerfile 中的 VOLUME
指令)。 ADD
和 COPY
命令仅在 docker build
为 运行 时复制文件。在使用 docker build
命令创建新图像之前,这些文件不会更新。相比之下,使用卷本质上是说 "this directory should not be stored in the container image; instead use a directory on the host";每当卷内的文件发生更改时,主机和容器都会立即看到它。
我不相信你可以使用卷实现你想要的,如果你想这样做,你将不得不重新考虑你的目录结构。
然而,使用 COPY
(应该优于 ADD
)实现起来非常简单。您可以使用 .dockerignore
文件来排除子目录,或者您可以 COPY
所有文件然后执行 RUN rm bla
来删除子目录。
请记住,您使用 COPY
或 ADD
添加到图像的任何文件都必须在构建上下文中,即在您 运行 docker build
所在的目录中或目录下。
使用 docker-compose 我可以在本地使用 node_modules,但在 docker 容器中使用 docker-compose.yml
[= 中的以下语法忽略它16=]
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
这会将您的当前目录挂载为共享卷,但会挂载一个永久性 docker 卷来代替您的本地 node_modules
目录。这类似于@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
选项(归功于 ), but --mount
is clearer and recommended。
对于同样遇到 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
未被本地覆盖的地方进行良好工作流程的人来说,这可能会有所帮助。
- 更改您的 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.
假设我的主机 /hostFolder
上有一个 Docker 容器和一个文件夹。现在,如果我想将此文件夹作为卷添加到 Docker 容器中,那么我可以通过在 Dockerfile
中使用 ADD
或将其作为卷安装来执行此操作。
到目前为止,还不错。
现在 /hostFolder
包含子文件夹 /hostFolder/subFolder
。
我想将 /hostFolder
挂载到 Docker 容器中(无论是读写还是只读都无所谓,对我来说都适用),但我这样做 NOT 想要包含它 /hostFolder/subFolder
。我想排除这一点,我还希望 Docker 容器能够对此子文件夹进行更改,而不会在主机上也进行更改。
这可能吗?如果是,怎么做?
首先,在 Dockerfile 中使用 ADD
指令与使用卷 非常 不同(通过 -v
参数 docker run
或 Dockerfile 中的 VOLUME
指令)。 ADD
和 COPY
命令仅在 docker build
为 运行 时复制文件。在使用 docker build
命令创建新图像之前,这些文件不会更新。相比之下,使用卷本质上是说 "this directory should not be stored in the container image; instead use a directory on the host";每当卷内的文件发生更改时,主机和容器都会立即看到它。
我不相信你可以使用卷实现你想要的,如果你想这样做,你将不得不重新考虑你的目录结构。
然而,使用 COPY
(应该优于 ADD
)实现起来非常简单。您可以使用 .dockerignore
文件来排除子目录,或者您可以 COPY
所有文件然后执行 RUN rm bla
来删除子目录。
请记住,您使用 COPY
或 ADD
添加到图像的任何文件都必须在构建上下文中,即在您 运行 docker build
所在的目录中或目录下。
使用 docker-compose 我可以在本地使用 node_modules,但在 docker 容器中使用 docker-compose.yml
[= 中的以下语法忽略它16=]
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
这会将您的当前目录挂载为共享卷,但会挂载一个永久性 docker 卷来代替您的本地 node_modules
目录。这类似于@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
选项(归功于 --mount
is clearer and recommended。
对于同样遇到 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
未被本地覆盖的地方进行良好工作流程的人来说,这可能会有所帮助。
- 更改您的 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.