我尝试使用 docker 命令行运行 docker 镜像,但未指定卷的名称。现在我发现我想继续使用此容器/镜像,但需要在 docker compose 中定义容器。
什么是最佳实践如何保存匿名/未命名卷中的数据并在 docker compose 创建的新容器中使用它们?
- 我可以以某种方式将未命名的卷转换为命名的卷吗?
- 或者我应该用docker compose创建一个带有命名卷的新容器并复制数据?
- 或者还有其他选择吗?
答案1
目前无法重命名现有卷。(无论这些卷之前是否已命名,还是未命名且其名称已自动生成,都是如此。)
您可以看到这个问题以获取有关此功能实现的更多信息,以及添加您的“+1”/“赞”以让开发人员知道您想要它。
如果没有这个,据我所知,唯一的好方法就是创建新的命名卷并复制数据。
答案2
总结一下解决方法:
# Safe steps
docker volume create --name <new_volume>
docker run --rm -it \
-v <old_volume>:/from:ro \
-v <new_volume>:/to \
alpine \
ash -c "cd /from ; cp -av . /to"
# Danger: Run this only when absolutely certain everything copied correctly.
docker volume rm <old_volume>
这种方法的好处是:
- 使用docker API,因此几乎可以兼容任何运行docker的操作系统。
- 它使用一个名为的轻量级 Linux 映像
alpine
。 - 它使用 的
alpine
默认 shellash
来运行文件复制,cp -av
从旧卷到新命名的卷。 - 为了安全起见,它将原始卷安装为只读并复制它而不是移动它。
答案3
在撰写本文时,唯一的选择是复制数据。具体细节可能因您的具体设置而异。要执行的一般步骤如下:
停止并移除源容器以便在步骤3中创建新的卷。
docker stop NAME docker rm NAME # or docker-compose stop SERVICE docker-compose rm SERVICE
在某些情况下,您可能能够推迟删除源容器,例如从
docker-compose
匿名卷切换到docker-compose
命名卷时。在这种情况下up
将创建新卷。然后您可以继续复制数据。但即使在这种情况下,也建议停止容器以避免在复制数据时更改数据。并且您必须删除源容器才能docker-compose
切换到新卷(注意警告)。在某些情况下它并不是真正需要的,例如从独立容器切换到时
docker-compose
。如果适用则进行更改
docker-compose.yml
。为要创建的新卷启动新容器。
独立容器:
docker run ... # or docker-compose up -d
停止新的容器以避免数据被更改。
docker stop ... # or docker-compose stop
如果要迁移到具有命名卷的独立容器,您可以创建卷来代替启动/停止容器。
复制数据。
docker run --rm -v "SRC_VOLUME:/from" -v "DST_VOLUME:/to" \ bash -c ' shopt -s dotglob # rm -r /to/* # e.g. pg might have populated the new volume cp -r /from/* /to '
其中 SRC_VOLUME、DST_VOLUME - 卷名称、ID 或主机上目录的绝对路径。
要列出连接到容器的卷,请使用:
docker inspect CONTAINER --format '{{json .Mounts}}' | jq
其中 CONTAINER - 容器名称或 ID。
启动新的容器。
docker run ... # or docker-compose up -d
欢喜吧:)
如果你想尝试不同的设置,请查看以下内容要旨。
答案4
我在寻找有关命名卷的信息时找到了这篇文章。我知道这是一篇旧帖子,但读完后我做了一些研究,发现至少目前有可能将文件系统导出为 tarball, 和将 tarball 导入到图像或作为图像。
首先导出容器的文件系统:
docker container export -o filename CONTAINER
在创建新容器之后 / 时将 tarball 导入到文件系统:
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
如果您指定一个档案,Docker 会在相对于 /(根)的容器中将其解压。
您还可以用这个小工具创建未标记的图像:
docker import filesystem.tar