持久化数据库

如果你没有注意到,你的 todo list 每次都是空的 您启动容器。为什么会这样?在这一部分中,您将深入了解容器的工作原理。

容器的文件系统

当容器运行时,它将镜像中的各个层用于其文件系统。 每个容器也有自己的 “暂存空间” 来创建/更新/删除文件。任何 更改不会在另一个容器中看到,即使它们使用相同的镜像。

在实践中查看

要查看实际效果,您将启动两个容器。在一个容器中, 您将创建一个文件。在另一个容器中,您将检查是否相同 文件存在。

  1. 启动 Alpine 容器并在其中创建新文件。

    $ docker run --rm alpine touch greeting.txt
    

    提示

    您在镜像名称后指定的任何命令(在本例中为 ) 在容器内执行。在这种情况下,该命令将一个名为 file 的文件放在容器的文件系统上。alpinetouch greeting.txtgreeting.txt

  2. 运行新的 Alpine 容器,并使用命令检查该文件是否存在。stat

    $ docker run --rm alpine stat greeting.txt
    

    您应该会看到类似于以下内容的输出,指示新容器中不存在该文件。

    stat: can't stat 'greeting.txt': No such file or directory
    

第一个容器创建的文件在 第二个容器。这是因为每个容器的可写 “顶层” 被隔离。即使两个容器共享相同的底层层,即 组成基础镜像时,可写层对于每个容器都是唯一的。greeting.txt

容器卷

在前面的实验中,您看到每个容器每次启动时都从镜像定义开始。 虽然容器可以创建、更新和删除文件,但当您删除容器时,这些更改会丢失 Docker 隔离对该容器的所有更改。使用卷,您可以更改所有这些。

提供了连接 将容器返回到主机。如果您在容器中挂载一个目录,则该目录中的更改 目录中。如果您在容器重启时挂载相同的目录,您将看到 相同的文件。

卷有两种主要类型。您最终会同时使用两者,但您将从卷挂载开始。

持久化 todo 数据

默认情况下,todo 应用程序将其数据存储在容器文件系统中的 SQLite 数据库中。如果您不熟悉 SQLite,不用担心!它只是一个将所有数据存储在一个文件中的关系数据库。虽然这不是大规模应用程序的最佳选择, 它适用于小型演示。稍后您将了解如何将其切换到其他数据库引擎。/etc/todos/todo.db

由于数据库是单个文件,如果您可以将该文件持久保存在主机上并使其可供 next container,它应该能够从上一个容器中断的地方继续。通过创建卷并附加 (通常称为 “mounting”) 将其保存到存储数据的目录中,则可以持久保存数据。作为您的容器 写入文件时,它会将数据持久保存到卷中的主机。todo.db

如前所述,您将使用卷挂载。将卷挂载视为不透明的数据桶。 Docker 完全管理卷,包括磁盘上的存储位置。您只需要记住 卷的名称。

创建卷并启动容器

您可以使用 CLI 或 Docker Desktop 的图形界面创建卷并启动容器。


  1. 使用命令创建卷。docker volume create

    $ docker volume create todo-db
    
  2. 再次使用 , 停止并删除 todo 应用容器 因为它仍在运行,而不使用持久卷。docker rm -f <id>

  3. 启动 todo 应用容器,但添加选项以指定 卷挂载。为卷命名,并将其挂载到 container,用于捕获在该路径中创建的所有文件。--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

要创建卷:

  1. 在 Docker Desktop 中选择 Volumes
  2. Volumes (卷) 中,选择 Create (创建)。
  3. 指定为卷名称,然后选择 Create (创建)。todo-db

要停止和删除应用程序容器,请执行以下操作:

  1. 选择 Docker Desktop 中的容器。
  2. 在容器的 Actions (操作) 列中选择 Delete (删除)。

要在挂载了卷的情况下启动 todo 应用程序容器:

  1. 选择 Docker Desktop 顶部的搜索框。

  2. 在搜索窗口中,选择 Images 选项卡。

  3. 在搜索框中,指定镜像名称 。getting-started

    提示

    使用搜索筛选条件筛选镜像并仅显示本地镜像

  4. 选择您的镜像,然后选择 Run (运行)。

  5. 选择 Optional settings (可选设置)。

  6. Host port (主机端口) 中,指定端口,例如 .3000

  7. Host path (主机路径) 中,指定卷的名称 。todo-db

  8. Container path (容器路径) 中,指定 。/etc/todos

  9. 选择 Run (运行)。


验证数据是否持续存在

  1. 容器启动后,打开应用程序并将一些项目添加到您的待办事项列表中。

    Items added to todo list
  2. 停止并删除 todo 应用的容器。使用 Docker Desktop 或 获取 ID,然后将其删除。docker psdocker rm -f <id>

  3. 使用前面的步骤启动新容器。

  4. 打开应用程序。您应该会看到您的项目仍在您的列表中。

  5. 签出完列表后,请继续删除容器。

您现在已经学习了如何持久保存数据。

深入了解卷

很多人经常问“当我使用卷时,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 访问权限才能从主机访问此目录。Mountpoint

总结

在本节中,您学习了如何持久保存容器数据。

相关信息:

后续步骤

接下来,您将了解如何使用绑定挂载更高效地开发应用程序。