为何基于同一镜像的新Docker容器会与旧容器拥有相同自定义文件?
问题:为何新启动的Metabase容器会包含旧容器的自定义文件?
我用以下命令启动了第一个Metabase容器:
docker run -d -p 8000:3001 -v metabase-data:/metabase-data -v ~/metabase-plugins:/plugins -e "MB_DB_FILE=/metabase-data" --name metabase-main metabase/metabase
之后通过docker cp把自定义文件复制到容器内的/metabase-data/和/plugins/目录,这两个目录原本是空的。
接着用几乎相同的命令启动了第二个容器,仅端口和容器名称不同:
docker run -d -p 8001:3002 -v metabase-data:/metabase-data -v ~/metabase-plugins:/plugins -e "MB_DB_FILE=/metabase-data" --name metabase-test metabase/metabase
检查新容器metabase-test内的/metabase-data/和/plugins/目录时,发现它们和旧容器metabase-main有相同的自定义文件,这是为什么?
原因分析
这是Docker**卷(Volume)和绑定挂载(Bind Mount)**的共享特性导致的,具体分两种情况:
命名卷
metabase-data的共享- 你用
-v metabase-data:/metabase-data创建的是Docker命名卷,这类卷由Docker统一管理,不属于任何单个容器。 - 当你向第一个容器的
/metabase-data目录复制文件时,实际是将文件写入了这个命名卷中。 - 第二个容器同样挂载了
metabase-data卷到自身的/metabase-data目录,因此会直接读取卷中已存在的文件——命名卷的核心设计目的就是支持多容器间的数据共享。
- 你用
绑定挂载
~/metabase-plugins:/plugins的共享- 你用
-v ~/metabase-plugins:/plugins配置的是绑定挂载,它直接将宿主机的~/metabase-plugins目录映射到容器内的/plugins路径。 - 由于绑定挂载是双向同步的,当你通过
docker cp向第一个容器的/plugins复制文件时,实际上是写入了宿主机的~/metabase-plugins目录。 - 第二个容器同样挂载了宿主机的这个目录,所以容器内
/plugins会显示宿主机目录里的所有文件,包括你之前复制的自定义文件。
- 你用
简言之,这两种挂载方式的核心作用就是实现容器间或容器与宿主机间的数据共享,因此新启动的容器会自动获取已存在的文件。
内容的提问来源于stack exchange,提问作者Mike Abbey
相关产品推荐
相关产品推荐

