Skip to content

使用绑定挂载

原文:https://docs.docker.com/get-started/06_bind_mounts/

第五部分中,你使用了卷挂载来持久化数据库中的数据。当你需要一个持久的地方来存储应用程序数据时,卷挂载是一个很好的选择。

绑定挂载是另一种类型的挂载,它允许你从宿主机的文件系统共享一个目录到容器中。在开发应用程序时,你可以使用绑定挂载将源代码挂载到容器中。容器可以立即看到你对代码所做的更改,只要你保存了一个文件。这意味着你可以在容器中运行监视文件系统更改并响应这些更改的进程。

在本章中,你将看到如何使用绑定挂载和一个名为 nodemon 的工具来监视文件更改,然后自动重启应用程序。大多数其他语言和框架中也有类似的工具。

快速比较卷类型

以下是使用 --mount 的命名卷和绑定挂载的示例:

  • 命名卷:type=volume,src=my-volume,target=/usr/local/data
  • 绑定挂载:type=bind,src=/path/to/data,target=/usr/local/data

以下表格概述了卷挂载和绑定挂载之间的主要差异。

命名卷绑定挂载
宿主位置Docker 选择你决定
使用容器内容填充新卷
支持卷驱动程序

尝试绑定挂载

在了解如何使用绑定挂载开发你的应用程序之前,你可以运行一个快速实验,以获得绑定挂载工作方式的实际理解。

  1. 验证你的 getting-started-app 目录是否在 Docker Desktop 的文件共享设置中定义的目录内。此设置定义了你可以与容器共享的文件系统的哪些部分。有关访问设置的详细信息,请参阅关于 MacWindowsLinux 的主题。

  2. 打开终端并更改目录到 getting-started-app 目录。

  3. 运行以下命令,在 ubuntu 容器中使用绑定挂载启动 bash

    console
    docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash

    --mount type=bind 选项告诉 Docker 创建一个绑定挂载,其中 src 是你宿主机上的当前工作目录(getting-started-app),target 是该目录在容器内应出现的位置(/src)。

  4. 运行命令后,Docker 在容器的文件系统根目录中启动一个

交互式 bash 会话。

console
root@ac1237fad8db:/# pwd
/
root@ac1237fad8db:/# ls
bin   dev  home  media  opt   root  sbin  srv  tmp  var
boot  etc  lib   mnt    proc  run   src   sys  usr
  1. 更改目录到 src 目录。

    这是你在启动容器时挂载的目录。列出此目录的内容会显示与你宿主机上的 getting-started-app 目录中的文件相同。

    console
    root@ac1237fad8db:/# cd src
    root@ac1237fad8db:/src# ls
    Dockerfile  node_modules  package.json  spec  src  yarn.lock
  2. 创建一个名为 myfile.txt 的新文件。

    console
    root@ac1237fad8db:/src# touch myfile.txt
    root@ac1237fad8db:/src# ls
    Dockerfile  myfile.txt  node_modules  package.json  spec  src  yarn.lock
  3. 在宿主机上打开 getting-started-app 目录,观察目录中是否有 myfile.txt 文件。

    text
    ├── getting-started-app/
    │ ├── Dockerfile
    │ ├── myfile.txt
    │ ├── node_modules/
    │ ├── package.json
    │ ├── spec/
    │ ├── src/
    │ └── yarn.lock
  4. 在宿主机上删除 myfile.txt 文件。

  5. 在容器中,再次列出 app 目录的内容。观察文件现在已经消失。

    console
    root@ac1237fad8db:/src# ls
    Dockerfile  node_modules  package.json  spec  src  yarn.lock
  6. 使用 Ctrl + D 停止交互式容器会话。

这就是关于绑定挂载的简要介绍。这个过程演示了文件如何在宿主和容器之间共享,以及如何立即在双方反映更改。现在你可以使用绑定挂载来开发软件。

开发容器

使用绑定挂载对于本地开发设置很常见。其优势在于开发机器不需要安装所有的构建工具和环境。通过单个 docker run 命令,Docker 会拉取依赖和工具。

在开发容器中运行你的应用

以下步骤描述了如何运行一个开发容器,其中包括一个绑定挂载,用于执行以下操作:

  • 将你的源代码挂载到容器中
  • 安装所有依赖
  • 启动 nodemon 来监视文件系统更改

你可以使用 CLI 或 Docker Desktop 来运行你的容器,并使用绑定挂载。

  1. 确保你当前没有正在运行的 getting-started 容器。

  2. getting-started-app 目录运行以下命令。

    console
    docker run -dp 127.0.0.1:3000:3000 \
        -w /app --mount type=bind,src="$(pwd)",target=/app \
        node:18-alpine \
        sh -c "yarn install && yarn run dev"

    以下是命令的解析:

    • -dp 127.0.0.1:3000:3000 - 与之前相同。以分离(后台)模式运行并创建端口映射
    • -w /app - 设置“工作目录”或命令将从中运行的当前目录
    • --mount type=bind,src="$(pwd)",target=/app - 将宿主机上的当前目录绑定挂载到容器中的 /app 目录
    • node:18-alpine - 使用的镜像。注意这是你的应用 Dockerfile

中的基础镜像

  • sh -c "yarn install && yarn run dev" - 命令。你正在使用 sh 启动一个 shell(alpine 没有 bash)并运行 yarn install 安装包,然后运行 yarn run dev 启动开发服务器。如果你查看 package.json,你会看到 dev 脚本启动了 nodemon
  1. 你可以使用 docker logs <container-id> 查看日志。当你看到以下内容时,你就知道已经准备好了:

    console
    docker logs -f <container-id>
    nodemon -L src/index.js
    [nodemon] 2.0.20
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): *.*
    [nodemon] watching extensions: js,mjs,json
    [nodemon] starting `node src/index.js`
    Using sqlite database at /etc/todos/todo.db
    Listening on port 3000

    当你完成查看日志后,通过按 Ctrl+C 退出。

使用开发容器开发你的应用

更新你宿主机上的应用,并在容器中看到反映的更改。

  1. src/static/js/app.js 文件中,在第 109 行,将“Add Item”按钮更改为简单的“Add”:

    diff
    - {submitting ? 'Adding...' : 'Add Item'}
    + {submitting ? 'Adding...' : 'Add'}

    保存文件。

  2. 刷新你的网络浏览器页面,你应该几乎立即看到更改反映出来,因为绑定挂载。Nodemon 检测到更改并重启服务器。Node 服务器重启可能需要几秒钟。如果遇到错误,请在几秒钟后尝试刷新。

    更新后的添加按钮标签的截图

  3. 随意进行任何其他你想要的更改。每次你做出更改并保存文件时,由于绑定挂载,更改会在容器中反映出来。当 Nodemon 检测到更改时,它会自动重启容器内的应用。当你完成时,停止容器并使用以下命令构建你的新镜像:

    console
    docker build -t getting-started .

总结

至此,你可以持久化你的数据库,并在开发过程中看到你的应用更改,而无需重新构建镜像。

除了卷挂载和绑定挂载之外,Docker 还支持其他挂载类型和存储驱动程序,用于处理更复杂和专门的用例。

相关信息:

下一步

为了准备你的应用进入生产环境,你需要将数据库从在 SQLite 中工作迁移到可以更好扩展的东西。为了简化,你将继续使用关系数据库,并将你的应用切换到使用 MySQL。但是,你应该如何运行 MySQL?你应该如何允许容器相互通信?你将在下一节中学习到这些内容。