当前位置: 首页 > news >正文

【Docker】容器挂载文件修改后 Commit 新镜像,挂载文件不会更新

【Docker】容器挂载文件修改后 Commit 新镜像,挂载文件不会更新

  • 问题描述:
  • 场景验证
    • 1. 自定义镜像 Dockerfile
    • 2. 创建 hello.txt 文件:
    • 3. 构建自定义镜像
    • 4. 运行镜像,并检查容器内部文件内容
    • 5. 新增挂载目录,并修改,验证 Commit 的新镜像
  • 总结
    • 1. docker commit 时不会抓取容器挂载的文件系统;
    • 2. 解决办法
      • 2.1 直接在 Dockerfile 中更新文件:
      • 2.2 将文件复制到容器并重新构建

问题描述:

在使用某个镜像的时候,由于需要频繁修改镜像中的某些文件,于是就将这些文件所在的文件夹挂载到宿主机上了,在需要更新的时候,直接更新宿主机上挂载的目录下的文件来达到更新容器中的文件。

上面的骚操作,看似没什么问题,实际也是正常可用的。

最多是修改完挂载路径下面的文件,然后重启一下容器,修改就生效了,省时省力,不用重新构建镜像了。

但是在需要打版本,更新成新的镜像时,问题就暴露出来了,Commit 的新镜像发现某个路径下面的文件竟然不是最新的。

如果不是特意瞅一眼新镜像内挂载目录下的文件的时间,这打着新版本旗号的镜像,里子却是旧的文件,如果没有发现,那么可能在某个阳光明媚的午后,一回头,一颗子弹正中眉心。。。。。

场景验证

1. 自定义镜像 Dockerfile

创建一个自定义镜像,并让它持续运行,Dockerfile 内容如下:

# 使用 busybox 作为基础镜像
FROM busybox:latest# 在容器中创建一个目录
RUN mkdir -p /data# 将宿主机的文件复制到容器中的 /data 目录
COPY hello.txt /data/hello.txt# 设置容器启动后执行的命令
CMD ["sh", "-c", "while true; do sleep 3600; done"]

步骤说明

  • FROM busybox:latest: 使用 busybox:latest 作为基础镜像。
  • RUN mkdir -p /data: 在容器内创建 /data 目录。
  • COPY hello.txt /data/hello.txt: 将宿主机上的 hello.txt 文件复制到容器的 /data 目录。请确保在构建镜像的目录中存在 hello.txt 文件。
  • CMD [“sh”, “-c”, “while true; do sleep 3600; done”]: 设置容器启动后执行的命令,使容器持续运行,每小时休眠一次。

2. 创建 hello.txt 文件:

在与 Dockerfile 相同的目录中,创建一个 hello.txt 文件,添加一些内容:

echo "Hello from custom busybox image" > hello.txt

3. 构建自定义镜像

在 Dockerfile 所在目录中运行以下命令来构建镜像:

docker build -t my_custom_busybox .
[root@VM-0-5-centos test_busybox]# docker build -t my_custom_busybox .
Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM busybox:latest
latest: Pulling from library/busybox
ec562eabd705: Pull complete 
Digest: sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7
Status: Downloaded newer image for busybox:latest---> 65ad0d468eb1
Step 2/4 : RUN mkdir -p /data---> Running in 8f33e3fc38e5
Removing intermediate container 8f33e3fc38e5---> 05e6ea4bdc10
Step 3/4 : COPY hello.txt /data/hello.txt---> 3f4301a9012e
Step 4/4 : CMD ["sh", "-c", "while true; do sleep 36000; done"]---> Running in cf5704c53a4c
Removing intermediate container cf5704c53a4c---> 2d188d99b7f8
Successfully built 2d188d99b7f8
Successfully tagged my_custom_busybox:latest
[root@VM-0-5-centos test_busybox]# 

可以看到,构建了一个新的镜像,并且在镜像里面预置了自定义了一个文件;

4. 运行镜像,并检查容器内部文件内容

新建 docker-compose.yaml 文件,内容如下:

version: "3.1"
services:# my-custom-busyboxmy-custom-busybox:image: my_custom_busybox:1.0.1container_name: my-custom-busyboxhostname: my-custom-busyboxrestart: alwaysdeploy:resources:limits:cpus: '1'memory: 1G# volumes:#   - ./data:/data/

第一次运行,查看预置文件内容时,先不挂载目录,直接运行:

[root@VM-0-5-centos test_busybox]# docker-compose up -d 
[+] Running 1/1⠿ Container my-custom-busybox  Started                                                                                                                                                                                                                   10.9s
[root@VM-0-5-centos test_busybox]# 

进入容器内部,查看预置文件内容:

[root@VM-0-5-centos test_busybox]# docker exec -it my-custom-busybox sh
/ # 
/ # 
/ # ls /data/
/ # 
/ # ls /data/
hello.txt
/ # 
/ # cat /data/hello.txt 
Hello from custom busybox image
/ # 

可以看到,当前镜像运行的容器,确实是我们之前构建镜像时的文件内容;

5. 新增挂载目录,并修改,验证 Commit 的新镜像

在当前目录下新建文件夹,并新增一个同名文件,来覆盖容器内的文件:

mkdir data
echo "Updated content from host" > ./data/hello.txt 

打开上面 docker-compose.yaml 文件中的注释,新的内容如下:

version: "3.1"
services:# my-custom-busyboxmy-custom-busybox:image: my_custom_busybox:latestcontainer_name: my-custom-busyboxhostname: my-custom-busyboxrestart: alwaysdeploy:resources:limits:cpus: '1'memory: 1Gvolumes:- ./data:/data/

保存后,再次启动:

[root@VM-0-5-centos test_busybox]# docker rm -f my-custom-busybox 
my-custom-busybox
[root@VM-0-5-centos test_busybox]# 
[root@VM-0-5-centos test_busybox]# docker-compose up -d           
[+] Running 1/1⠿ Container my-custom-busybox  Started   

为了保险起见,我这里先删除了旧的容器,然后启动新的容器;

再次进入容器内查看 /data/hello.txt 文件内容:

[root@VM-0-5-centos data]# docker exec -it my-custom-busybox sh
/ # 
/ # cat /data/hello.txt 
Updated content from host
/ # 

可以看到,在挂载目录之后,容器内的同名文件确实被覆盖了,并且在宿主机上修改,容器内也是实时生效的。

接着验证 Commit 新镜像:

[root@VM-0-5-centos data]# docker ps | grep busybox
861e5b55ea63   my_custom_busybox:latest                                             "sh -c 'while true; …"   2 minutes ago    Up 2 minutes                                                                                                  my-custom-busybox
[root@VM-0-5-centos data]# 
[root@VM-0-5-centos data]# docker commit -m "update volume file content" 861e5b55ea63 my_custom_busybox:1.0.1
sha256:d8986fb86d74b0d5eae145a89780fad62b6335502ad9013bf17f169f0edee1fa
[root@VM-0-5-centos data]# 

这里将当前已经挂载了的容器 Commit 成一个新的镜像,镜像为:my_custom_busybox:1.0.1

修改 docker-compose.yaml 文件中的镜像版本为my_custom_busybox:1.0.1,然后重新启动容器,再次进入容器内查看文件内容:

[root@VM-0-5-centos test_busybox]# docker-compose up -d 
[+] Running 1/1⠿ Container my-custom-busybox  Started                                                                                                                                                                                                                   10.9s
[root@VM-0-5-centos test_busybox]# 
/ # [root@VM-0-5-centos data]# docker exec -it my-custom-busybox sh
/ # 
/ # 
/ # cat /data/hello.txt 
Hello from custom busybox image
/ # 

发现文件内容还是原来构建镜像时的内容;

总结

1. docker commit 时不会抓取容器挂载的文件系统;

Docker 中,容器挂载的文件系统变化不会影响到通过 docker commit 创建的新镜像,因为 docker commit 只会保存容器的层,而不会保存挂载点的内容。

2. 解决办法

2.1 直接在 Dockerfile 中更新文件:

FROM busybox:latest
COPY path/to/your/files /path/in/container

修改 Dockerfile,然后重新构建镜像。这种方式最直接,可以确保所有更改都被纳入到新的镜像中。

使用 docker build 构建镜像:docker build -t my_updated_image .

2.2 将文件复制到容器并重新构建

通过 docker cp 将文件从宿主机复制到运行中的容器中,然后使用 docker commit 创建新镜像。这种方法会包含手动修改后的文件。

[root@VM-0-5-centos test_busybox]# cat data/hello.txt 
Updated content from host
[root@VM-0-5-centos test_busybox]# 
[root@VM-0-5-centos test_busybox]# docker cp  data/hello.txt my-custom-busybox:/data/
[root@VM-0-5-centos test_busybox]# docker ps  | grep busy
aeab9533145f   my_custom_busybox:1.0.1                                              "sh -c 'while true; …"   3 hours ago     Up 3 hours                                                                                                    my-custom-busybox
[root@VM-0-5-centos test_busybox]# 
[root@VM-0-5-centos test_busybox]# docker commit -m "docker cp and commit new images " aeab9533145f my_custom_busybox:1.0.2
sha256:0212216bf47dcdd9dfbf3184bdbdf9e44ce1d86238a0ca4290079a54f7104ee0
[root@VM-0-5-centos test_busybox]# 
[root@VM-0-5-centos test_busybox]# docker-compose up -d 
[+] Running 1/1⠿ Container my-custom-busybox  Started                                                                                                                                                                                                                   10.9s
[root@VM-0-5-centos test_busybox]# docker exec -it my-custom-busybox sh
/ # 
/ # cat /data/hello.txt 
Updated content from host
/ # 
/ # 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 用Python实现时间序列模型实战——Day 6: ARIMA 模型的理论基础
  • R 语言学习教程,从入门到精通,R 绘图饼图(23)
  • Flink 1.14.* Flink窗口创建和窗口计算源码
  • 链动2+1与消费增值模式的协同效应
  • NestJs bull 用法
  • Linux驱动开发基础(sr04超声波模块)
  • 算法day16|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
  • filezilla使用教程(window下filezilla使用教程)
  • 梧桐数据库(WuTongDB):什么是“顺序扫描”
  • [GESP202312 四级] 田忌赛马
  • 今日算法:蓝桥杯基础题之“星系炸弹”
  • 掌握 Python列表:从基础到进阶技巧
  • FutureTask通常如何使用?
  • Ethercat设备数据 转IEC61850项目案例
  • django学生就业管理系统—计算机毕业设计源码24237
  • [译]前端离线指南(上)
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • const let
  • eclipse(luna)创建web工程
  • gcc介绍及安装
  • If…else
  • Objective-C 中关联引用的概念
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Python学习笔记 字符串拼接
  • SpingCloudBus整合RabbitMQ
  • Swift 中的尾递归和蹦床
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Vue.js源码(2):初探List Rendering
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 闭包,sync使用细节
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 开发基于以太坊智能合约的DApp
  • 免费小说阅读小程序
  • 深度解析利用ES6进行Promise封装总结
  • 小程序 setData 学问多
  • 学习使用ExpressJS 4.0中的新Router
  • 06-01 点餐小程序前台界面搭建
  • 如何在招聘中考核.NET架构师
  • ​configparser --- 配置文件解析器​
  • # windows 运行框输入mrt提示错误:Windows 找不到文件‘mrt‘。请确定文件名是否正确后,再试一次
  • #if 1...#endif
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (3)(3.5) 遥测无线电区域条例
  • (编译到47%失败)to be deleted
  • (二)原生js案例之数码时钟计时
  • (二十三)Flask之高频面试点
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (小白学Java)Java简介和基本配置
  • (一)模式识别——基于SVM的道路分割实验(附资源)
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转载)从 Java 代码到 Java 堆
  • *Django中的Ajax 纯js的书写样式1
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .mysql secret在哪_MySQL如何使用索引