使用 bind mounts 向容器提供额外数据

未匹配的标注

在上一节中,我们讨论并使用了 named volume 将数据持久保存在数据库中。如果我们只想简单的存储数据,那么 named volume 就够用了,因为我们不必关心数据的存储位置。

这一节,将在介绍另外一种 volume 类型,即:bind mounts
使用 bind mounts 我们可以控制主机上的准确挂载点。虽然也可以用它来保存数据,但是通常是用它来向容器提供额外数据。比如:我们可以使用 bind mounts 将主机上的源代码挂载到容器中,以便容器可以及时感知源代码的变更。

对于基于 Node.js 的应用程序,[nodemon](https://npmjs.com/package/nodemon)是监视文件更改然后重新启动应用程序的好工具。大多数其他语言和框架都有类似的工具。

两种不同 Volume 类型的比较

named volumesbind mounts 是 Docker 引擎内置的两种主要 Volume 类型。也可以使用其他类型的 Volume 驱动程序来支持其他使用场景,如 SFTPCephNetAppS3 等…

Named Volumes Bind Mounts
在主机上的位置 由 Docker 自动选择 由你自己决定
挂载示例 (使用 -v 标记) my-volume:/usr/local/data /path/to/data:/usr/local/data
使用容器内容填充新 volume
支持 Volume 驱动程序

启动一个开发模式的容器

为了运行一个支持开发工作流程的容器,我们将执行以下操作:

  • 将我们的源代码挂载到容器中
  • 安装所有依赖项,包括 dev 依赖项
  • 启动 nodemon 来监听文件变化

让我们开始吧:

  1. 删除之前启动的 todo-app 容器

  2. 执行以下命令:

    docker run -dp 3000:3000 \
        -w /app \
        -v "$(pwd):/app" \
        node:12-alpine \
        sh -c "yarn install && yarn run dev"

    如果使用的是 PowerShell,执行下面这条命令(只是 多行输入 的分隔符不一样而已)

    docker run -dp 3000:3000 `
        -w /app `
        -v "$(pwd):/app" `
        node:12-alpine `
        sh -c "yarn install && yarn run dev"
    • -dp 3000:3000 - 之前遇到过了,表示让容器保持在后台运行并做好端口映射
    • -w /app - 设置 “working directory” - 工作目录
    • -v "$(pwd):/app" - bind mount 主机上的当前目录挂载到容器上的 /app 目录
    • node:12-alpine - 使用的镜像
    • sh -c "yarn install && yarn run dev" - 在容器中执行两条命令。由于 alpine 没有 bash,所以通过 sh 执行这两条命令,第一条:yarn install 安装我们程序用到的依赖;第二条:yarn run dev 启动服务。如果我们查看 package.json 文件就会发现 dev 脚本正是使用能够监听文件变化并自动重启服务的 nodemon(一旦主机上的源码有变化,它能及时监听到,并自动重启 todo-app 服务)
  3. 由于上一条命令会在容器中执行安装依赖的操作,在不同的网络环境下的执行时间可能快也可能慢,因此需要等待一会才能访问我们的服务。可以通过 docker logs 命令查看容器日志,先执行 docker image ls 查看容器ID,再执行 docker logs -f <container-id> 命令,如果看到日志输出了 Listening on port 3000 就代表我们的程序已经启动成功。

    docker logs -f <container-id>
    
    yarn install ...
    [1/4] Resolving packages...
    [2/4] Fetching packages...
    ......
    [3/4] Linking dependencies...
    [4/4] Building fresh packages...
    Done in 93.42s.
    ......
    $ nodemon src/index.js
    [nodemon] 1.19.2
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching dir(s): *.*
    [nodemon] starting `node src/index.js`
    Using SQLite database at /etc/todos/todo.db
    Listening on port 3000

    看完日志后,按 Ctrl + C 退出。

  4. 现在,让我们来再一次修改源代码。将 src/static/js/app.js 文件第 109 行的 “Add Item” 改成 “Add”

  5. 只需刷新应用的首页,几乎就能立即在浏览器中看到更改。容器内部自动重新启动 Node 服务器可能需要花费几秒钟的时间,因此,如果访问页面出现错误,可以稍等几秒钟后再试。
    Screenshot of updated label for Add button

  6. 至此,你可以随时在本机对应用程序源码进行任何更改。完成后,停止容器并使用 docker build -t todo-app . 重新构建新镜像。
    在本地开发模式下,使用 bind mounts 非常普遍。它的优点是使得本地开发机器不需要安装所有构建工具和环境。只需一条 docker run 命令,开发环境就准备就绪了。

回顾

本节我们学习了如何通过 bind mounts 快速搭建本地开发环境。

下一节我们准备将数据库从 SQLite 改成更适合生产环境使用的 MySQL。那么问题来了,我们该如何运行 MySQL? 如何让不同容器之间彼此通信?下节再详细说明。

原始资料:Using Bind Mounts

配套视频
www.bilibili.com/video/BV1WZ4y1w7p...

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~