与容器共享本地文件

解释

每个容器都拥有运行所需的一切,无需依赖主机上任何预安装的依赖项。由于容器是独立运行的,因此它们对主机和其他容器的影响最小。这种隔离有一个主要好处:容器可以最大限度地减少与主机系统和其他容器的冲突。但是,这种隔离也意味着默认情况下容器无法直接访问主机上的数据。

考虑这样一个场景:您有一个 Web 应用程序容器,该容器需要访问存储在主机系统上的文件中的配置设置。此文件可能包含敏感数据,例如数据库凭证或 API 密钥。将此类敏感信息直接存储在容器镜像中会带来安全风险,尤其是在镜像共享期间。为了应对这一挑战,Docker 提供了存储选项,以弥合容器隔离和主机数据之间的差距。

Docker 提供了两个主要存储选项,用于在主机和容器之间保存数据和共享文件:卷和绑定挂载。

卷挂载与绑定挂载

如果要确保在容器停止运行后,容器内生成或修改的数据仍然存在,则可以选择卷。请参阅持久化容器数据以了解有关卷及其使用案例的更多信息。

如果主机系统上有要直接与容器共享的特定文件或目录,例如配置文件或开发代码,则可以使用绑定挂载。这就像在主机和容器之间打开一个直接的门户进行共享。绑定挂载非常适合实时文件访问以及主机和容器之间的共享至关重要的开发环境。

在主机和容器之间共享文件

与命令一起使用的 (或 ) 和标志都允许您在本地计算机(主机)和 Docker 容器之间共享文件或目录。但是,它们的行为和用法存在一些关键差异。-v--volume--mountdocker run

该标志更简单、更方便用于基本卷或绑定挂载操作。如果在使用 或 时主机位置不存在,则将自动创建目录。-v-v--volume

假设您是一名从事项目的开发人员。您在代码所在的开发计算机上有一个 source 目录。编译或构建代码时,生成的工件(编译的代码、可执行文件、镜像等)将保存在源目录中的单独子目录中。在以下示例中,此子目录为 .现在,您希望这些构建工件可以在运行应用程序的 Docker 容器中访问。此外,您希望容器在您重新构建代码时自动访问最新的构建工件。/HOST/PATH

这是一种使用绑定挂载启动容器并将其映射到容器文件位置的方法。docker run

$ docker run -v /HOST/PATH:/CONTAINER/PATH -it nginx

该标志提供更高级的功能和精细控制,使其适用于复杂的挂载场景或生产部署。如果您用于绑定挂载 Docker 主机上尚不存在的文件或目录,则该命令不会自动为您创建它,但会生成错误。--mount--mountdocker run

$ docker run --mount type=bind,source=/HOST/PATH,target=/CONTAINER/PATH,readonly nginx

注意

Docker 建议使用 语法而不是 .它可以更好地控制挂载过程,并避免缺少目录的潜在问题。--mount-v

Docker 访问主机文件的文件权限

使用绑定挂载时,确保 Docker 具有访问主机目录所需的权限至关重要。要授予读/写访问权限,您可以在容器创建期间将标志 (read-only) 或 (read-write) 与 or 标志一起使用。 例如,以下命令授予读写访问权限。:ro:rw-v--mount

$ docker run -v HOST-DIRECTORY:/CONTAINER-DIRECTORY:rw nginx

只读绑定挂载允许容器访问主机上挂载的文件以进行读取,但不能更改或删除这些文件。使用读写绑定挂载,容器可以修改或删除挂载的文件,这些更改或删除也将反映在主机系统上。只读绑定挂载可确保容器不会意外修改或删除主机上的文件。

同步文件共享

随着代码库的增大,传统的文件共享方法(如绑定挂载)可能会变得效率低下或速度变慢,尤其是在需要频繁访问文件的开发环境中。同步文件共享通过利用同步文件系统缓存来提高绑定挂载性能。这种优化可确保主机和虚拟机 (VM) 之间的文件访问快速高效。

试用

在本动手指南中,您将练习如何创建和使用绑定挂载在主机和容器之间共享文件。

运行容器

  1. 下载并安装Docker 桌面。

  2. 通过以下命令使用 httpd 镜像启动容器:

    $ docker run -d -p 8080:80 --name my_site httpd:2.4
    

    这将在后台启动服务,并将网页发布到主机上的端口。httpd8080

  3. 打开浏览器并访问 http://localhost:8080 或使用 curl 命令验证它是否正常工作。

    $ curl localhost:8080
    

使用绑定挂载

使用绑定挂载,您可以将主机上的配置文件映射到容器中的特定位置。在此示例中,你将了解如何使用 bind mount 更改网页的外观:

  1. 使用 Docker Desktop Dashboard 删除现有容器:

    Docker Desktop Dashboard 的屏幕截图,显示如何删除 httpd 容器
  2. 在主机系统上创建一个名为 的新目录。public_html

    $ mkdir public_html
    
  3. 将目录更改为并创建一个名为 file with the following content.这是一个基本的 HTML 文档,它创建了一个简单的网页,以友好的鲸鱼欢迎您。public_htmlindex.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title> My Website with a Whale & Docker!</title>
    </head>
    <body>
    <h1>Whalecome!!</h1>
    <p>Look! There's a friendly whale greeting you!</p>
    <pre id="docker-art">
       ##         .
      ## ## ##        ==
     ## ## ## ## ##    ===
     /"""""""""""""""""\___/ ===
    {                       /  ===-
    \______ O           __/
    \    \         __/
     \____\_______/
    
    Hello from Docker!
    </pre>
    </body>
    </html>
  4. 是时候运行容器了。和 examples 产生相同的结果。除非在运行第一个容器后删除容器,否则无法同时运行这两个容器。--mount-vmy_site


    $ docker run -d --name my_site -p 8080:80 -v .:/usr/local/apache2/htdocs/ httpd:2.4
    
    $ docker run -d --name my_site -p 8080:80 --mount type=bind,source=./,target=/usr/local/apache2/htdocs/ httpd:2.4
    

    提示

    在 Windows PowerShell 中使用 or 标志时,您需要提供目录的绝对路径,而不仅仅是 .这是因为 PowerShell 处理相对路径的方式与 bash(通常用于 Mac 和 Linux 环境)不同。-v--mount./

    现在一切都准备就绪并运行,您应该能够通过 http://localhost:8080 访问该网站并找到一个以友好的鲸鱼欢迎您的新网页。

在 Docker Desktop Dashboard 上访问文件

  1. 您可以通过选择容器的 Files (文件) 选项卡,然后选择目录中的文件来查看容器内挂载的文件。然后,选择 Open file editor(打开文件编辑器)。/usr/local/apache2/htdocs/

    Docker Desktop Dashboard 的屏幕截图显示了容器内挂载的文件
  2. 删除主机上的文件,并验证该文件是否已在容器中删除。您会发现 Docker Desktop Dashboard 中的 Files 下不再存在这些文件。

    Docker Desktop Dashboard 的屏幕截图,显示容器内已删除的文件
  3. 在主机系统上重新创建 HTML 文件,并看到该文件重新出现在 Docker Desktop Dashboard 上 Containers 下的 Files 选项卡下。到目前为止,您也可以访问该站点。

停止容器

容器将继续运行,直到您停止它。

  1. 转到 Docker Desktop Dashboard 中的 Containers 视图。

  2. 找到要停止的容器。

  3. 在 Actions 列中选择 Delete 操作。

显示如何删除容器的 Docker Desktop Dashboard 的屏幕截图

其他资源

以下资源将帮助您了解有关绑定挂载的更多信息:

后续步骤

现在,您已经了解了如何与容器共享本地文件,是时候了解多容器应用程序了。