如何在主机之间迁移Docker卷?
Docker指出卷可以“迁移”——我假设这意味着我应该能够将卷从一台主机移动到另一台主机。(非常高兴在这一点上得到纠正。)但是,同一文档页面没有提供如何做到这一点的信息 仔细研究一下,我发现了一个问题(大约在2015年),表明这是不可能的,但考虑到已经过去了2年,我想我应该再问一次 如果有帮助的话,我正在开发一个Flask应用程序,它使用[TinyDB]+本地磁盘作为数据存储——我已经确定我不需要比这更奇特的东西了;这是目前为学习而做的一个项目,所以我决定做一个非常轻量级的项目。该项目的结构如下:如何在主机之间迁移Docker卷?,docker,flask,docker-volume,Docker,Flask,Docker Volume,Docker指出卷可以“迁移”——我假设这意味着我应该能够将卷从一台主机移动到另一台主机。(非常高兴在这一点上得到纠正。)但是,同一文档页面没有提供如何做到这一点的信息 仔细研究一下,我发现了一个问题(大约在2015年),表明这是不可能的,但考虑到已经过去了2年,我想我应该再问一次 如果有帮助的话,我正在开发一个Flask应用程序,它使用[TinyDB]+本地磁盘作为数据存储——我已经确定我不需要比这更奇特的东西了;这是目前为学习而做的一个项目,所以我决定做一个非常轻量级的项目。该项目的结构如下
/project_directory
|- /app
|- __init__.py
|- ...
|- run.py # assumes `data/databases/ and data/files/` are present
|- Dockerfile
|- data/
|- databases/
|- db1.json
|- db2.json
|- files/
|- file1.pdf
|- file2.pdf
我的.dockrignore
和.gitignore
中有文件夹data/*
,因此它们不受版本控制,Docker在构建图像时会忽略它们
在开发应用程序的过程中,我还尝试使用尽可能接近真实世界的数据库条目和PDF,因此我在应用程序中植入了非常小的真实数据子集,这些数据存储在一个卷上,当Docker容器实例化时直接装入数据/
我想做的是将容器部署到远程主机上,但让远程主机使用starter数据(理想情况下,这将是我在本地使用的卷,以获得最大的便利);稍后,随着更多的数据添加到远程主机上,我希望能够将其拉回,以便在开发过程中使用最终用户输入的最新数据
环顾四周,我想到的“黑客”方式就是简单地使用
rsync
,这可能会很好。然而,如果我缺少一个解决方案,我将非常感谢您的指导 我实现这一点的方法是生成一个Docker容器,该容器存储您想要为您的开发环境播种的数据的副本。然后可以将该容器中的数据作为卷公开,最后将该卷装载到开发容器中。我将用一个例子来演示:
创建数据容器
首先,我们将创建一个Docker容器,其中包含种子数据,而不包含其他内容。我将在~/data/Dockerfile
创建一个Dockerfile
,并为其提供以下内容:
FROM alpine:3.4
ADD . /data
VOLUME /data
CMD /bin/true
然后,您可以使用以下内容构建此功能:
docker build-t myproject/myseed数据。
这将创建一个Docker图像,标记为myproject/myseed data:latest
。该图像仅包含您想要为环境播种的所有数据,存储在图像中的/data
。每当我们将映像的实例创建为容器时,它都会将/data
中的所有文件作为卷公开
将卷装入另一个Docker容器中
我想象您正在运行Docker容器,如下所示:
version: 2
services:
seed-data:
image: myproject/my-seed-data:latest
my_app:
build: .
volumes_from:
- seed-data
depends_on:
- seed-data
docker run-d-v$(pwd)/data:/data您的容器图像
现在,您可以将其扩展为执行以下操作:
docker run -d --name seed-data myproject/my-seed-data
docker run -d --volumes-from seed-data your-container-image <start_up_command>
然后,您可以使用docker compose up-d my_app
一次启动所有容器。Docker Compose足够聪明,可以首先启动数据容器的实例,最后启动应用程序容器
在主机之间共享数据容器
最简单的方法是将数据容器作为图像推送到。构建映像后,可以将其推送到Docker Hub,如下所示:
docker推送myproject/my种子数据:最新
它在概念上非常类似于将Git提交推送到远程存储库,而在本例中,您推的是Docker映像。然而,这意味着任何环境现在都可以提取此图像并使用其中包含的数据。这意味着您可以在拥有新种子数据时重新生成数据映像,将其推送到Docker Hub的:latest
标记下,并且当您重新启动开发环境时,将拥有最新的数据
对我来说,这是共享数据的“Docker”方式,它使数据在Docker环境之间保持可移植性。您还可以在像Jenkins这样的CI环境中通过作业定期生成数据容器。您可以使用以下技巧:
docker run --rm -v <SOURCE_DATA_VOLUME_NAME>:/from alpine ash -c "cd /from ; tar -cf - . " | ssh <TARGET_HOST> 'docker run --rm -i -v <TARGET_DATA_VOLUME_NAME>:/to alpine ash -c "cd /to ; tar -xpvf - " '
docker-run--rm-v:/from alpine ash-c“cd/from;tar-cf-.“|ssh”docker-run--rm-i-v:/to alpine ash-c”cd/to;tar-xpvf-“'
这可能很有用,因为这样做了!“非常感谢,”罗伯·布莱克!:D:D:Da快速跟进问题,如果您愿意帮忙的话:假设我的远程主机上的用户添加了新数据,我想在本地将其拉回,而不必执行
docker commit
s(我听说它很快就会变丑),有什么方法可以做到这一点吗?@ericmjl例如,您可以docker cp
从容器中取出数据,基于该数据构建另一个数据容器,将新的数据容器推送到docker Hub,然后docker将其拉到本地。上述内容可以每天编写脚本,并由CI服务器(如Jenkins)管理。有道理?