持久化数据库

如果您没有注意到,每次启动容器时,您的待办事项列表都是空的。这是为什么?在本部分中,您将深入了解容器的工作原理。

容器的文件系统

当容器运行时,它使用镜像中的各个层作为其文件系统。每个容器还获得自己的“临时空间”来创建/更新/删除文件。任何更改都不会在另一个容器中看到,即使它们使用的是同一个镜像。

实践中查看

要查看此操作,您将启动两个容器。在一个容器中,您将创建一个文件。在另一个容器中,您将验证文件是否存在。您将看到,在一个容器中创建的文件在另一个容器中不可用。

  1. 启动一个 Alpine 容器并访问其 shell。

    $ docker run -ti --name=mytest alpine
    
  2. 在容器中,使用 hello 在其中创建一个名为 greeting.txt 的文件。

    / # echo "hello" > greeting.txt
    
  3. 退出容器。

    / # exit
    
  4. 运行一个新的 Alpine 容器,并使用 cat 命令验证文件是否不存在。

    $ docker run alpine cat greeting.txt
    

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

    cat: can't open 'greeting.txt': No such file or directory
    
  5. 继续使用 docker ps --all 获取 ID,然后使用 docker rm -f <container-id> 删除容器。

容器卷

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

提供将容器的特定文件系统路径连接回主机的能力。如果您在容器中挂载目录,则该目录中的更改也会在主机上看到。如果您在容器重启时挂载了相同的目录,您将看到相同的文件。

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

持久化待办事项数据

默认情况下,待办事项应用程序将数据存储在容器文件系统中的 /etc/todos/todo.db 中的 SQLite 数据库中。如果您不熟悉 SQLite,不用担心!它只是一个将所有数据存储在一个文件中的关系数据库。虽然这对于大型应用程序来说不是最好的,但它适用于小型演示。您将学习如何稍后将其切换到不同的数据库引擎。

由于数据库只是一个文件,如果您可以在主机上持久化该文件并使其对下一个容器可用,它应该能够从上一个容器停止的地方继续。通过创建一个卷并将其附加(通常称为“挂载”)到您存储数据的目录,您可以持久化数据。当您的容器写入 todo.db 文件时,它将数据持久化到主机上的卷中。

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

创建卷并启动容器

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


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

    $ docker volume create todo-db
    
  2. 使用 docker rm -f <id> 再次停止并删除待办事项应用程序容器,因为它仍在运行,没有使用持久卷。

  3. 启动待办事项应用程序容器,但添加 --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 中选择**卷**。
  2. 在**卷**中,选择**创建**。
  3. 指定 todo-db 作为卷名称,然后选择**创建**。

要停止并删除应用程序容器

  1. 在 Docker Desktop 中选择**容器**。
  2. 在容器的**操作**列中选择**删除**。

要使用挂载的卷启动待办事项应用程序容器

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

  2. 在搜索窗口中,选择**镜像**选项卡。

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

    提示

    使用搜索过滤器筛选镜像,仅显示**本地镜像**。

  4. 选择您的镜像,然后选择**运行**。

  5. 选择**可选设置**。

  6. 在**主机端口**中,指定端口,例如 3000

  7. 在**主机路径**中,指定卷的名称 todo-db

  8. 在**容器路径**中,指定 /etc/todos

  9. 选择**运行**。


验证数据是否持久化

  1. 容器启动后,打开应用程序并在待办事项列表中添加几个项目。

    Items added to todo list
  2. 停止并删除待办事项应用程序的容器。使用 Docker Desktop 或 docker ps 获取 ID,然后使用 docker 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"
    }
]

Mountpoint 是数据在磁盘上的实际位置。请注意,在大多数机器上,您需要具有 root 权限才能从主机访问此目录。

总结

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

相关信息

下一步

接下来,您将学习如何使用绑定挂载更有效地开发您的应用程序。