Docker 挂载到文件夹覆盖内容

Posted

技术标签:

【中文标题】Docker 挂载到文件夹覆盖内容【英文标题】:Docker mount to folder overriding content 【发布时间】:2018-05-19 17:35:54 【问题描述】:

我有一个 .net Core Web Api,其配置文件位于名为 Config 的文件夹下。 我从中创建了图像和一个容器,并且我使用终端正确地看到容器包含文件夹和内部的配置文件。

我的问题是,到目前为止,我找不到一种方法来创建相同的容器,按照要求将 Config 文件夹安装/绑定到物理路径:

1) 将 Config 文件夹挂载到特定的主机位置

2) 创建容器时,Config 文件夹中应填入镜像中的文件

3) 在创建容器时,用映像中的文件覆盖文件夹中已经存在的任何现有文件

4) 能够从主机自定义文件夹中的配置文件

我的创建命令:

    docker --tls -H="$containerUrl" `
        create `
        --hostname $hostname `
        --name $containerName `
        --mac-address=$containerMacAddress `
        --ip $containerIpAddress `
        --net "bridged-network" `
        --workdir '/app' `
        --mount type=bind,src=$configVolumePath,target=/app/Config `
        --publish "0.0.0.0::80" `
        -t `
        -i $imageName":"$script:buildversion    

使用 --mount 和类型 bind,如文档中所述,如果文件夹中有任何文件,则这些文件隐藏在容器和应用程序中将看到部署的文件。 这个解决方案的问题是我无法从主机更新配置文件夹中的文件。

现在,删除 type=bind 我得到了相同的结果,但令人困惑。

我尝试使用卷 --volume $configVolumePath":/app/Config:rw",但这样做不会覆盖主机目录中的预先存在的文件,并且这些文件是将在容器内使用。

补充说明,我没有在 Dockerfile 中指定任何内容或撰写与卷挂载相关的内容,我也没有尝试创建卷然后将其用作源,但我认为这不会产生区别。

容器服务器在 NAS 上运行,版本如下:

 Version:      1.11.2
 API version:  1.23
 Go version:   go1.5.4
 Git commit:   781516c
 Built:        Thu Aug  3 16:04:05 2017
 OS/Arch:      linux/amd64

显然我遗漏了一些东西,我必须了解有关 docker 的更多信息,有人可以帮忙吗?

我的参考资料:

1) https://docs.docker.com/engine/admin/volumes/bind-mounts/

2) https://docs.docker.com/engine/admin/volumes/volumes/

【问题讨论】:

【参考方案1】:

首先,docker 卷或绑定挂载的行为类似于 linux 挂载。

如果主机卷/挂载存在并包含文件,它将“覆盖”容器中的任何内容。如果不是,容器文件将被镜像到主机卷/挂载上,并且容器文件夹和主机将同步。 在这两种情况下,在主机上编辑文件总是会反映在容器内。

在您的情况下,您可以执行以下操作:

docker volume create --driver local \
    --opt type=none \
    --opt device=$configVolumePath \
    --opt o=bind \
    config_vol

这将创建一个卷,该卷将保存在主机上的 $configVolumePath 中。

创建容器时使用该卷:

docker create --volume config_vol:/app/Config

您将得到的是在启动时,主机文件夹将是空的,并且图像中的文件将被“复制”到主机文件夹中。 $configVolumePath 中的编辑文件将反映在容器内,类似地 在容器/app/Config 内编辑的文件将反映在主机上的$configVolumePath 中。

【讨论】:

谢谢yamenk,所以我的问题是我没有删除文件夹的内容。我尝试创建卷,它的行为与您描述的一样。为了仔细检查我的理解是否正确,不需要卷的实际“预”创建,将卷参数作为 docker create 的一部分传递就足够了,我今晚会尝试。有什么方法可以通过一些 --opt 参数来强制删除/覆盖文件夹内容?请注意,为了运行您建议的脚本,我必须使用参数 --name config_vol 太棒了!我正在寻找传递给本地卷驱动程序的选项,但在绑定挂载的任何地方都找不到它们! HOURS...不...在过去几年中,使用 docker 试图找到一个体面的解决方案没有浪费任何时间。 您应该向 docker 文档提交一些此类知识,因为他们关于使用 --bind / mounts 的文档通常是迟钝的 (IMO)。 我这辈子都找不到我可以通过 --driver 传递的不同选项

以上是关于Docker 挂载到文件夹覆盖内容的主要内容,如果未能解决你的问题,请参考以下文章

docker的复制和挂载

docker中启用挂载卷,docker中的新文件会不会同步到

Docker容器数据卷挂载使用

Docker持久化存储之数据共享

docker挂载文件后变成目录

有条件地在 docker-compose 中挂载卷