持久化数据库
如果你没注意到,每次启动容器时,你的待办事项列表都是空的。这是为什么呢?在这一部分,你将深入了解容器是如何工作的。
容器的文件系统
当容器运行时,它使用镜像中的各个层作为其文件系统。 每个容器都有自己的“临时空间”来创建/更新/删除文件。任何 更改都不会在另一个容器中看到,即使它们使用的是同一个镜像。
在实践中查看此内容
为了看到实际效果,您将启动两个容器。在一个容器中, 您将创建一个文件。在另一个容器中, 您将检查该文件是否存在。
启动一个 Alpine 容器并在其中创建一个新文件。
$ docker run --rm alpine touch greeting.txt提示
您在镜像名称后(在本例中为
alpine)指定的任何命令 都在容器内执行。在本例中,命令touch greeting.txt将一个名为greeting.txt的文件 放置在容器的文件系统上。运行一个新的 Alpine 容器并使用
stat命令检查文件是否存在。$ docker run --rm alpine stat greeting.txt您应该看到类似以下的输出,表明该文件在新容器中不存在。
stat: can't stat 'greeting.txt': No such file or directory
由第一个容器创建的 greeting.txt 文件在第二个容器中不存在。这是因为每个容器的可写“顶层”是隔离的。尽管两个容器共享构成基础镜像的相同底层层,但可写层是每个容器独有的。
容器卷
在上一个实验中,您看到每个容器在每次启动时都从镜像定义开始。 虽然容器可以创建、更新和删除文件,但当您删除容器时,这些更改会丢失, 并且Docker隔离了对该容器的所有更改。通过卷,您可以改变这一切。
卷 提供了将容器的特定文件系统路径连接回主机的能力。如果你在容器中挂载一个目录,该目录中的更改也会在主机上看到。如果你在容器重启时挂载同一个目录,你会看到相同的文件。
主要有两种类型的卷。您最终会使用这两种类型,但您将从卷挂载开始。
持久化待办事项数据
默认情况下,todo 应用将其数据存储在容器文件系统中的 /etc/todos/todo.db 位置的 SQLite 数据库中。如果您不熟悉 SQLite,不用担心!它只是一个将所有数据存储在单个文件中的关系数据库。虽然这对大规模应用来说不是最佳选择,但对于小型演示来说已经足够。您稍后将学习如何将其切换到不同的数据库引擎。
由于数据库是一个单独的文件,如果您可以将该文件持久化到主机上并使其对下一个容器可用,那么该容器应该能够从上一个容器停止的地方继续工作。通过创建一个卷并将其附加(通常称为“挂载”)到您存储数据的目录,您可以持久化数据。当您的容器写入 todo.db 文件时,它会将数据持久化到主机上的卷中。
如前所述,您将使用一个卷挂载。可以将卷挂载视为一个不透明的数据桶。 Docker 完全管理该卷,包括磁盘上的存储位置。您只需记住 该卷的名称。
创建卷并启动容器
您可以使用CLI或Docker Desktop的图形界面创建卷并启动容器。
使用
docker volume create命令创建一个卷。$ docker volume create todo-db再次使用
docker rm -f <id>停止并移除 todo app 容器,因为它仍在运行且未使用持久化卷。启动待办事项应用容器,但添加
--mount选项以指定卷挂载。为卷指定一个名称,并将其挂载到容器中的/etc/todos,这将捕获在该路径下创建的所有文件。$ docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started注意
如果您正在使用 Git Bash,则必须为此命令使用不同的语法。
$ docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=//etc/todos getting-started有关 Git Bash 语法差异的更多详情,请参阅 使用 Git Bash。
要创建卷:
- 在 Docker Desktop 中选择 Volumes。
- 在 卷 中,选择 创建。
- 将卷名指定为
todo-db,然后选择 创建。
要停止并移除应用容器:
- 在 Docker Desktop 中选择容器。
- 在操作列中选择删除以删除容器。
要启动带有挂载卷的待办事项应用程序容器:
选择 Docker Desktop 顶部的搜索框。
在搜索窗口中,选择 镜像 标签页。
在搜索框中,指定镜像名称,
getting-started。提示
使用搜索过滤器来筛选镜像,仅显示本地镜像。
选择您的镜像,然后选择 运行。
选择可选设置。
在主机端口中,指定端口,例如,
3000。在 主机路径 中,指定卷的名称,
todo-db。在 容器路径 中,指定
/etc/todos。选择 运行。
验证数据是否持久化
容器启动后,打开应用程序并向您的待办事项列表中添加一些项目。

停止并移除待办事项应用程序的容器。使用 Docker Desktop 或
docker ps获取 ID,然后使用docker rm -f <id>移除它。使用前面的步骤启动一个新的容器。
打开应用程序。您应该看到您的项目仍然在列表中。
在您完成检查列表后,请继续删除容器。
您已经学会了如何持久化数据。
深入卷
很多人经常问“当我使用卷时,Docker将我的数据存储在哪里?”如果您想知道,您可以使用 docker volume inspect 命令。
$ docker volume inspect todo-db
您应该看到类似以下的输出:
[
{
"CreatedAt": "2019-09-26T02:18:36Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
"Name": "todo-db",
"Options": {},
"Scope": "local"
}
]
Mountpoint 是数据在磁盘上的实际位置。请注意,在大多数机器上,您需要具有 root 权限才能从主机访问此目录。
摘要
在本节中,您学习了如何持久化容器数据。
相关信息:
后续步骤
接下来,您将学习如何使用绑定挂载更高效地开发您的应用程序。