持久化数据库
您可能没有注意到,每次启动容器时,您的待办事项列表都是空的。这是为什么呢?在本部分中,您将深入了解容器的工作原理。
容器的文件系统
容器运行时,它使用镜像中的各个层作为其文件系统。每个容器还会获得自己的“临时空间”来创建/更新/删除文件。即使它们使用的是相同的镜像,其他容器也看不到任何更改。
实际操作
要查看其运行情况,您将启动两个容器。在一个容器中,您将创建一个文件。在另一个容器中,您将检查该文件是否存在。
启动一个 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 将所有更改隔离到该容器。
使用卷,您可以更改所有这些。卷提供了一种功能,可以将容器的特定文件系统路径连接回主机。如果挂载容器中的目录,则该目录中的更改也会显示在主机上。如果在容器重启时挂载相同的目录,您将看到相同的文件。
卷主要有两种类型。您最终会同时使用这两种类型,但您将从卷挂载开始。
持久化待办事项数据
默认情况下,待办事项应用程序将其数据存储在容器文件系统中的/etc/todos/todo.db
中的 SQLite 数据库中。如果您不熟悉 SQLite,不用担心!它只是一个关系数据库,将所有数据存储在一个文件中。虽然这对于大型应用程序来说不是最佳选择,但它适用于小型演示。稍后您将学习如何将其切换到不同的数据库引擎。
由于数据库是一个文件,如果您可以将该文件持久化到主机并使其可用于下一个容器,则它应该能够从上一个容器中断的地方继续执行。通过创建一个卷并将其附加(通常称为“挂载”)到您存储数据的目录,您可以持久化数据。当您的容器写入todo.db
文件时,它将数据持久化到卷中的主机。
如前所述,您将使用卷挂载。将卷挂载视为一个不透明的数据桶。Docker 完全管理卷,包括磁盘上的存储位置。您只需要记住卷的名称。
创建卷并启动容器
您可以使用 CLI 或 Docker Desktop 的图形界面创建卷并启动容器。
使用
docker volume create
命令创建卷。$ docker volume create todo-db
使用
docker rm -f <id>
再次停止并删除待办事项应用程序容器,因为它仍在运行而没有使用持久卷。启动待办事项应用程序容器,但添加
--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 中选择**卷**。
- 在**卷**中,选择**创建**。
- 指定
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"
}
]
挂载点
是磁盘上数据的实际位置。请注意,在大多数机器上,您需要具有 root 权限才能从主机访问此目录。
总结
在本节中,您学习了如何持久化容器数据。
相关信息
后续步骤
接下来,您将学习如何使用绑定挂载更有效地开发您的应用程序。