【问题标题】:How to move a local volume onto a remote docker machine如何将本地卷移动到远程 docker 机器上
【发布时间】:2017-01-14 14:46:54
【问题描述】:

我在云端有本地 docker 机器和远程 docker 机器。我的 docker-compose 应用程序有一个 webcontainer 和这个配置:

web:
  container_name: web
  restart: always
  build: ./web
  expose:
    - "8000"
  links:
    - postgres:postgres
  volumes:
    - /usr/src/app/static
    - ./data:/usr/src/app/data
  env_file: .env
  command: /usr/local/bin/gunicorn --workers 4 --timeout 120 --bind :8000 app:app

重要的部分是第二卷。我有一个名为 data 的本地文件夹,里面有大约 10GB 的数据。我首先把它做成了一个卷,因为否则构建容器需要很长时间。现在该应用程序已准备好生产,我想部署它。一个问题:现在我的远程web 容器中安装了一个空数据文件夹。那么如何将数据从本地机器移动到远程 docker 机器上的容器中呢?我什至应该把它移到哪里

似乎有两个工具可以做到这一点:

  • docker cp 似乎不适用于远程 docker 机器
  • docker-machine scp 似乎是为此而生的,对吧?

我几乎肯定我需要使用其中的第二个,但由于我不太了解 docker 机器的工作原理或它保存数据的位置,我不确定要使用哪个目标路径:

  $  dm scp -r /Users/alex/Documents/Project/data remote-machine:/usr/src/app/data

失败并显示错误消息:

scp: /usr/src/app/data: No such file or directory

我应该在哪里对这些数据进行 scp 处理,以便将其正确挂载到我的远程 web 容器上?

【问题讨论】:

    标签: docker docker-compose docker-machine docker-volume


    【解决方案1】:

    本地路径与容器内路径

    假设您将使用与本地相同的远程模型,请记住路径 /usr/src/app/data 是容器内部的路径。当您将文件从一个系统复制到另一个系统时,您只需要将它们从当前系统复制到远程系统,然后将它们放在 docker-compose 知道如何找到它们的路径中,然后挂载到新容器中。

    所以你所要做的就是将它们从这里复制到那里,并使用相同的路径相对于docker-compose.yml。它只知道你的外部卷为./data,所以如果你把目录放在同一个地方(从docker-compose的角度来看),一切都应该是一样的。

    如何复制文件

    至于怎么复制,这些只是文件,无所谓。 scp -r 应该可以工作,或者制作一个 zip 文件,复制它,解压缩到正确的位置等。复制文件的方法有很多,所以选择最适合您的情况的方法。

    究竟需要复制什么?

    在 cmets 中,您对 docker-machine 中的本地操作与远程操作以及您还需要复制的内容表示混淆。这里有一个更完整的解释:

    在您的本地系统(我假设是您自己的 PC 或笔记本电脑)上,您安装了 docker-machine,并且您一直在使用它进行所有这些开发。与之完全不同的是您要部署的新云实例。

    要在本地运行您的云实例,云实例需要具备以下条件。

    1. docker-compose.yml 文件。

      只要你打算使用 docker-compose 来运行它,它就必须是可用的。

    2. 您的.env 文件。

      由于您在此设置中使用环境文件,它必须可用,否则 docker-compose 无法使用它。

    3. 您的web 图片。

      您有此容器的 build 参数,但没有 image 参数。所以目前你唯一能做的就是docker-compose build web,它将在本地生成一个图像,然后 docker-compose 知道如何运行。

      另一种选择是添加一个image 参数和repository:tag,例如myuser/myapp_web:1.0,然后将其推送到Docker Hub。然后,在您的云实例上,可以从 Docker Hub 检索图像,而不是在本地构建它。

      在这种情况下,你可以在 docker-compose.yml 中的web 容器中添加一个image 参数,然后构建它并向上推。

      docker-compose build web
      docker-compose push web
      

      然后在云实例上,你可以获取它:

      docker-compose pull web
      

      docker-compose 会知道使用该图像,因为 docker-compose.yml 中的 image 参数(也存在于云服务器上)。

      参考:Creating a new repository on Docker Hub

      这些选项中的哪一个更可取取决于您要如何管理事物。任何一个都可以,但“本地构建”选项需要您将任何所需的源文件也复制到您的云实例(在构建过程中使用的任何内容)。

    4. 我在您的问题中看不到 postgres 容器的来源。如果您也在定制这个,那么与web 相同。如果您为此使用公共图像,那么您不需要复制任何内容; docker-compose 将知道如何获取它,即您可以这样做:

      docker-compose pull postgres
      

    docker cp 和 docker-machine scp 呢?

    您在问题中提到了docker cpdocker-machine scp

    正如您已经确定的那样,docker cp 不是这里的解决方案。该命令用于在容器和主机文件系统之间复制文件。它与通过网络复制无关。

    据我所知,docker-machine scp 是在本地主机和docker-machine 托管的 VM 之间复制文件。要将文件复制到您的云实例,您可以更轻松地使用更通用的工具,例如 scp 或 sftp。

    【讨论】:

    • 感谢您的回答!我仍然有点困惑,主要是因为 docker-machine 如何使远程 docker 机器上的指令执行变得不透明,就好像它是我的本地机器一样。例如,在远程 docker 机器上,我找不到 docker-compose 文件,也找不到我的项目中的任何其他文件,这些文件应该位于容器本身之外。所以我真的不知道在上传data 时将它放在哪里,或者如何编辑 docker-compose 文件来编辑以设置我的远程卷的路径。这有意义吗?
    • 奇怪的是,我刚刚意识到远程机器上有一个/Users/alex/Documents/Project/data,似乎已经创建但为空。我将 docker-machine scp 数据放入该文件夹并查看会发生什么,但现在我收到权限被拒绝错误!
    • @AlexLenail 如果挂载目录不存在,docker-machine 会创建一个空目录。最有可能由容器内运行的任何东西的运行 uid 拥有。 (在 Dockerfile 中的 USER 语句中定义的用户,或者如果没有,则默认为 root。)如果您自己创建目录而不是让 docker-compose 来创建目录,那么您应该是所有者。
    • @AlexLenail 哦,如果您还没有阅读更新版本,我也在几分钟前更新了我的答案。我添加了一些关于需要复制的内容和原因的更多信息。
    • @AlexLenail 再次更新了我的答案,提到了 docker hub push/pull for images。
    【解决方案2】:

    不确定哪个 docker 版本,但与问题中的陈述和@Dan_Lowe 回答相反,这工作正常:

    docker cp ./data container:/usr/src/app/ 
    

    docker cp 是 API 的正常部分,因此它可以像任何其他命令一样工作,甚至是远程命令。

    【讨论】:

      猜你喜欢
      • 2017-04-27
      • 2017-10-23
      • 2015-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      相关资源
      最近更新 更多