如何将本地卷移动到远程 docker 机器上

How to move a local volume onto a remote docker machine

我有我的本地 docker 机器和一台远程 docker 机器,在云端。我的 docker-compose 应用有一个 web 容器,配置如下:

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 机器的工作原理或它保存数据的位置,我不确定目标路径是什么使用:

  $  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 容器上?

本地路径与in-container路径

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

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

如何复制文件

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

具体需要复制什么?

在评论中,您表达了对 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

    这些选项中的哪一个更可取取决于您希望如何管理事物。任何一个都可以,但 "local build" 选项将要求您将任何所需的源文件也复制到您的云实例(构建过程中使用的任何文件)。

  4. 我在你的问题中没有看到 postgres 容器的来源。如果你也是custom-building这个,那么web也是一样。如果您为此使用 public 图片,那么您不需要复制任何东西; 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 版本开始,但与问题中的陈述和@Dan_Lowe 的回答相反,这个工作正常:

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

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