Docker 实战之使用 Volume 保存容器内的数据

153 阅读3分钟

我们都知道每个容器都是独立的,那如果今天我想升级 MySQL 的版本,于是我把正在运行的 mysql:5.5 关闭,然后重新运行一个 mysql:5.7 的容器,那数据库里面的数据不就消失了吗?

没错,这时候就需要 volume 了,简单来说 Volume 就是用来保存容器内的数据的,看看下面这张图

image.png

当你使用 volume 时,Docker 会在你的本地随机创建一个文件夹作为本地存储区域,大部分情况下会在 /var 下面,然后让这个文件夹与容器内的某个文件夹互通

由于它们是相互连接的,所以当您容器中的文件夹发生任何更改时,本地文件夹也会相应变化。而且非常重要的一点是:即使容器被删除,该文件夹仍将完整保留在原处。因此,我们可以利用这个特性来保留容器内的数据

 实际操作

第一步 - 添加一个卷

我们新增了一个名为db-data的卷,完成后可以看到多了一个卷,此时Docker已经在本机上新增了一个文件夹供卷使用

> docker volume create --name db-data  
> docker volume ls

image.png

第二步 - 使用volume

在启动时加一个 -v 参数,就可以指定 volume 要跟容器内哪一个文件夹连通,这边用的是 /db/data ,实际上使用时可以换成数据库存放数据的路径

demo 一下:
刚开始先确认一下里面什么文件都没有。

  1. 然后在容器内添加一个文件 file
  2. 最后再确认文件是否存在
> docker run -v db-data:/db/data -it ubuntu ls -la /db/data
> docker run -v db-data:/db/data -it ubuntu touch /db/data/file
> docker run -v db-data:/db/data -it ubuntu ls -la /db/data

image.png

值得注意的是,这三个指令运行在不同的容器中,这证明了当容器被关闭时,数据确实保存在卷内,并且下一个容器可以成功读取上一个容器留下的数据

 主机容量

上面提到的那种先创建再使用的卷被称为命名卷,现在要介绍另外一种叫做主机卷的方式,用来直接指定主机上的某个文件夹与容器内的文件夹相连

来一段演示:

1.检查 ~/app 内没有 package.json

2.将本机的 ~/app 与容器内的 /app 连接起来,然后在容器内运行 npm init

3.跑完后再回到本机确认是否已经生成 package.json

> ls -la app
> docker run -v ~/app:/app --workdir /app node:slim npm init -y
> ls -la app

在上面的例子中,实际上 package.json 是在容器内生成的,因此一旦有了volume,就可以不必安装yarn,但仍然可以运行 yarn init

同样的道理,你甚至可以在不安装编译器的情况下编译C++源代码,也可以在不安装JDK的情况下开发Java程序,甚至可以在不安装MongoDB的情况下使用它来存储数据。只需在电脑上安装一个Docker,真是太神奇了🎉🎉