浅谈docker Dockerfile 指令 VOLUME 介绍

发布时间 - 2026-01-10 23:14:13    点击率:

在介绍VOLUME指令之前,我们来看下如下场景需求:

1)容器是基于镜像创建的,最后的容器文件系统包括镜像的只读层+可写层,容器中的进程操作的数据持久化都是保存在容器的可写层上。一旦容器删除后,这些数据就没了,除非我们人工备份下来(或者基于容器创建新的镜像)。能否可以让容器进程持久化的数据保存在主机上呢?这样即使容器删除了,数据还在。

2)当我们在开发一个web应用时,开发环境是在主机本地,但运行测试环境是放在docker容器上。

这样的话,我在主机上修改文件(如html,js等)后,需要再同步到容器中。这显然比较麻烦。

3)多个容器运行一组相关联的服务,如果他们要共享一些数据怎么办?

对于这些问题,我们当然能想到各种解决方案。而docker本身提供了一种机制,可以将主机上的某个目录与容器的某个目录(称为挂载点、或者叫卷)关联起来,容器上的挂载点下的内容就是主机的这个目录下的内容,这类似linux系统下mount的机制。 这样的话,我们修改主机上该目录的内容时,不需要同步容器,对容器来说是立即生效的。 挂载点可以让多个容器共享。

下面我们来介绍具体的机制。

一、通过docker run命令

1、运行命令:docker run --name test -it -v /home/xqh/myimage:/data ubuntu /bin/bash

其中的 -v 标记 在容器中设置了一个挂载点 /data(就是容器中的一个目录),并将主机上的 /home/xqh/myimage 目录中的内容关联到 /data下。

这样在容器中对/data目录下的操作,还是在主机上对/home/xqh/myimage的操作,都是完全实时同步的,因为这两个目录实际都是指向主机目录。

2、运行命令:docker run --name test1 -it -v /data ubuntu /bin/bash

上面-v的标记只设置了容器的挂载点,并没有指定关联的主机目录。这时docker会自动绑定主机上的一个目录。通过docker inspect 命令可以查看到。

xqh@ubuntu:~/myimage$ docker inspect test1
[
{
  "Id": "1fd6c2c4bc545163d8c5c5b02d60052ea41900a781a82c20a8f02059cb82c30c",
.............................
  "Mounts": [
    {
      "Name": "0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01",
      "Source": "/var/lib/docker/volumes/0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01/_data",
      "Destination": "/data",
      "Driver": "local",
      "Mode": "",
      "RW": true
    }
  ],
...........................

上面 Mounts下的每条信息记录了容器上一个挂载点的信息,"Destination" 值是容器的挂载点,"Source"值是对应的主机目录。

可以看出这种方式对应的主机目录是自动创建的,其目的不是让在主机上修改,而是让多个容器共享。

二、通过dockerfile创建挂载点

上面介绍的通过docker run命令的-v标识创建的挂载点只能对创建的容器有效。

通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。

还有一个区别是,通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。

#test
FROM ubuntu
MAINTAINER hello1
VOLUME ["/data1","/data2"]

上面的dockfile文件通过VOLUME指令指定了两个挂载点 /data1 和 /data2.

我们通过docker inspect 查看通过该dockerfile创建的镜像生成的容器,可以看到如下信息

  "Mounts": [
    {
      "Name": "d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21",
      "Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data",
      "Destination": "/data1",
      "Driver": "local",
      "Mode": "",
      "RW": true
    },
    {
      "Name": "6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36",
      "Source": "/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data",
      "Destination": "/data2",
      "Driver": "local",
      "Mode": "",
      "RW": true
    }
  ],

可以看到两个挂载点的信息。

三、容器共享卷(挂载点)

docker run --name test1 -it myimage /bin/bash

上面命令中的 myimage是用前面的dockerfile文件构建的镜像。 这样容器test1就有了 /data1 和 /data2两个挂载点。

下面我们创建另一个容器可以和test1共享 /data1 和 /data2卷 ,这是在 docker run中使用 --volumes-from标记,如:

可以是来源不同镜像,如:

docker run --name test2 -it --volumes-from test1 ubuntu /bin/bash

也可以是同一镜像,如:

docker run --name test3 -it --volumes-from test1 myimage /bin/bash

上面的三个容器 test1 , test2 , test3 均有 /data1 和 /data2 两个目录,且目录中内容是共享的,任何一个容器修改了内容,别的容器都能获取到。

四、最佳实践:数据容器

如果多个容器需要共享数据(如持久化数据库、配置文件或者数据文件等),可以考虑创建一个特定的数据容器,该容器有1个或多个卷。

其它容器通过--volumes-from 来共享这个数据容器的卷。

因为容器的卷本质上对应主机上的目录,所以这个数据容器也不需要启动。

如:

docker run --name dbdata myimage echo "data container"

说明:有个卷,容器之间的数据共享比较方便,但也有很多问题需要解决,如权限控制、数据的备份、卷的删除等。这些内容后续文章介绍。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# dockerfile  # volume  # volume指令  # Dockerfile中CMD和ENTRYPOINT命令详解  # 编写最佳的Dockerfile的方法  # 详解Dockerfile 中的 COPY 与 ADD 命令  # Docker中镜像构建文件Dockerfile与相关命令的详细介绍  # 详解利用Dockerfile构建mysql镜像并实现数据的初始化及权限设置  # Dockerfile中的ENV指令的具体使用详解  # Docker Dockerfile的使用实例  # Dockerfile制作官方Tomcat镜像及镜像使用详解  # Dockerfile中常用命令汇总  # 利用Dockerfile部署SpringBoot项目的方法  # 利用Dockerfile制作java运行环境的镜像的方法步骤  # docker Dockerfile文件制作自己的镜像的方法  # Dockerfile 指令 ADD 和 COPY介绍  # Dockerfile中multi-stage(多阶段构建)详解  # Docker 基础之Dockerfile命令详解  # 使用Dockerfile部署nodejs服务的方法步骤  # Dockerfile指令详解  # Docker构建文件Dockerfile简单入门  # 镜像  # 多个  # 都是  # 是在  # 可以看到  # 这样的话  # 这是  # 也不  # 我在  # 放在  # 有个  # 目录下  # 还在  # 有很多  # 不需要  # 都能  # 目录中  # 这两个  # 这类  # 但也 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 微信小程序 require机制详解及实例代码  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  利用vue写todolist单页应用  PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址  EditPlus中的正则表达式 实战(2)  如何在新浪SAE免费搭建个人博客?  如何在万网主机上快速搭建网站?  原生JS获取元素集合的子元素宽度实例  Laravel如何创建自定义Artisan命令?(代码示例)  零服务器AI建站解决方案:快速部署与云端平台低成本实践  详解jQuery停止动画——stop()方法的使用  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  JavaScript Ajax实现异步通信  详解jQuery中基本的动画方法  Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性  Android利用动画实现背景逐渐变暗  如何在局域网内绑定自建网站域名?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  Laravel如何使用Sanctum进行API认证?(SPA实战)  html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭  如何制作一个表白网站视频,关于勇敢表白的小标题?  Laravel怎么为数据库表字段添加索引以优化查询  Thinkphp 中 distinct 的用法解析  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南  如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环  Android okhttputils现在进度显示实例代码  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Swift中循环语句中的转移语句 break 和 continue  佛山企业网站制作公司有哪些,沟通100网上服务官网?  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  如何基于PHP生成高效IDC网络公司建站源码?  Android滚轮选择时间控件使用详解  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  企业网站制作这些问题要关注