搞懂Docker(六)- 持久化数据

在这里插入图片描述

获取示例程序

  1. 示例程序
    或者
    示例程序
    获取示例程序
  2. 程序结构如下
├── getting-started-app/
│ ├── package.json
│ ├── README.md
│ ├── spec/
│ ├── src/
│ └── yarn.lock

你可能没有注意到,每次你重新启动一个新的容器,todo列表都是空的。为什么会是这样呢?这篇文章,我们来看下容器是怎么工作的。

容器的文件系统

当一个容器启动后,它使用镜像里的不同的层作为文件系统。每个容器都有自己“一片天地”来执行文件的创建/更新/删除。任何变化在其他的容器中是看不到的,即使,它们用的是同一个镜像。

在示例中观察

要观察到这个现象,我们需要启动两个容器。在一个容器中,我们创建一个文件,在另外一个容器中,我们验证文件是否存在。

  1. 运行Alpine容器,并进入内部。
$ docker run -ti --name=mytest alpine
  1. 在容器中,创建一个greeting.txt文件,内容为hello
/ # echo "hello" > greeting.txt
  1. 退出容器
/ # exit
  1. 运行一个新的Alpine容器,并执行命令cat,验证文件是否存在。
$ docker run alpine cat greeting.txt

你应该会看到类似下面的输出,证明文件不存在。

cat: can't open 'greeting.txt': No such file or directory
  1. 移除容器,使用docker ps --all获得容器ID,使用docker rm -f <container-id>移除容器。

容器 volumes

根据之前的实验,我们看到每次都从镜像定义启动一个新的容器。容器创建、更新、删除文件,当你移除了容器,这些变化都丢失了。Docker隔离了这些变化。 利用volumes,我们可以改变现状。
volumes提供了容器的特定的文件系统跟宿主机的连接。如果你挂载一个容器内部的目录,该目录的变化会体现在宿主机上。
主要有两种类型的volumes,而且我们最后都会用到,我们先从volumes的挂载开始。

持久化todo的数据

默认情况下,todo程序把数据存储在SQLite数据库中,数据库文件在容器文件系统的/etc/todos/todo.db。如果你不熟悉SQLite,不用担心。它只是一个用一个文件存储数据的关系型数据库。当然,这个数据库不适合大型的程序,它只适用于小规模的程序。之后,我们会学习如何更换数据库系统。
由于数据库是一个单独的文件,如果你可以把这个文件持久化到宿主机上,之后的容器就可以用了,也就是说可以恢复之前停止的工作。我们可以创建一个volume,然后把它附加(也称挂载)到你容器内部存储数据的目录,就可以持久化数据了。你的容器一旦把数据写到todo.db文件,它就会把数据持久化到volume中。
你可以把volume的挂载看成是一个数据黑盒。Docker全权管理着volume,包括在宿主机磁盘上的存储位置。你只需要记住volume的名称即可。

创建一个volume并启动容器

  1. 使用volume create创建volume
$ docker volume create todo-db
  1. 使用docker rm -f <container-id>停止和移除之前运行的容器。
  2. 增加一个--mount选项,启动容器。给volume指定一个名字,然后把它挂载到容器中的/etc/todos,它会捕获这个目录下的所有文件。
$ docker run -dp 0.0.0.0:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started

验证数据是否持久化

  1. 容器启动之后,打开app,添加一些项。
    在这里插入图片描述
  2. 停止并移除容器。使用docker psdocker rm -f <container-id>
  3. 使用之前的命令启动一个新的容器。
  4. 打开app,你会发现之前添加的项还在。
  5. 做完验证后,停止并移除容器。

进入volume内部

我们可以执行docker volume inspect命令查看Docker把我们的数据存储到哪了。

$ docker volume inspect todo-db
[
    {
        "CreatedAt": "2024-05-11T10:15:17+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": null,
        "Scope": "local"
    }
]

Mountpoint就是实际存储数据的位置。访问这个位置需要root权限。

总结

本篇文章,我们学习了如何持久化数据。下一篇,我们介绍如何使用bind mounts更高效的开发程序。

  • 13
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值