Docker 将匿名卷转换为命名卷

Docker 将匿名卷转换为命名卷

我尝试使用 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

在撰写本文时,唯一的选择是复制数据。具体细节可能因您的具体设置而异。要执行的一般步骤如下:

  1. 停止并移除源容器以便在步骤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

  2. 如果适用则进行更改docker-compose.yml

  3. 为要创建的新卷启动新容器。

    独立容器:

    docker run ...
    # or
    docker-compose up -d
    
  4. 停止新的容器以避免数据被更改。

    docker stop ...
    # or
    docker-compose stop
    

    如果要迁移到具有命名卷的独立容器,您可以创建卷来代替启动/停止容器。

  5. 复制数据。

    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。

  6. 启动新的容器。

    docker run ...
    # or
    docker-compose up -d
    
  7. 欢喜吧:)

如果你想尝试不同的设置,请查看以下内容要旨

答案4

我在寻找有关命名卷的信息时找到了这篇文章。我知道这是一篇旧帖子,但读完后我做了一些研究,发现至少目前有可能将文件系统导出为 tarball, 和将 tarball 导入到图像或作为图像

首先导出容器的文件系统:

docker container export -o filename CONTAINER

在创建新容器之后 / 时将 tarball 导入到文件系统:

docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

如果您指定一个档案,Docker 会在相对于 /(根)的容器中将其解压。

您还可以用这个小工具创建未标记的图像:

docker import filesystem.tar

相关内容