【问题标题】:How to make volumes permanent with Docker Compose v2如何使用 Docker Compose v2 使卷永久化
【发布时间】:2016-02-25 07:32:23
【问题描述】:

我知道其他人也有类似的问题,但它使用 v2 compose 文件格式,我没有找到任何相关信息。

我想制作一个非常简单的测试应用程序来使用 MemSQL,但在 docker-compose down 之后我无法让卷不被删除。如果我对 Docker Docs 的理解正确,则不应该在没有明确告知的情况下删除卷。一切似乎都可以与docker-compose up 一起使用,但是在下降然后再次上升之后,所有数据都会从数据库中删除。

作为一个好的做法,我使用单独的 memsqldata 服务作为单独的数据层。

这是我的 docker-compose.yml:

version: '2'
services:
    app:
        build: .
        links:
            - memsql
    memsql:
        image: memsql/quickstart
        volumes_from:
            - memsqldata
        ports:
            - "3306:3306"
            - "9000:9000"
    memsqldata:
        image: memsql/quickstart
        command: /bin/true
        volumes:
            - memsqldatavolume:/data

volumes:
    memsqldatavolume:
        driver: local

【问题讨论】:

  • 我会尝试不使用 memsqldata 容器。由于您使用的是命名卷,因此不需要数据卷容器。我试过down,默认不删除任何卷。
  • 有没有可能mysql数据根本不在卷中?我不认为它通常使用/data

标签: docker docker-compose singlestore


【解决方案1】:

我意识到这是一个古老且已解决的线程,其中 OP 指向容器中的目录而不是它们已安装的卷,但想清除我看到的一些错误信息。

docker-compose down 不会删除卷,如果您还想删除卷,则需要运行 docker-compose down -v。这是直接来自 docker-compose 的帮助文本(注意“默认”列表):

$ docker-compose down --help
Stops containers and removes containers, networks, volumes, and images
created by `up`.

By default, the only things removed are:

- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used

Networks and volumes defined as `external` are never removed.

Usage: down [options]

Options:
...
    -v, --volumes       Remove named volumes declared in the `volumes` section
                        of the Compose file and anonymous volumes
                        attached to containers.
...

$ docker-compose --version
docker-compose version 1.12.0, build b31ff33

这是一个示例 yml,其中包含要测试的命名卷和一个虚拟命令:

$ cat docker-compose.vol-named.yml
version: '2'

volumes:
  data:

services:
  test:
    image: busybox
    command: tail -f /dev/null
    volumes:
    - data:/data

$ docker-compose -f docker-compose.vol-named.yml up -d
Creating volume "test_data" with default driver
Creating test_test_1

启动容器后,卷初始化为空,因为该位置的映像为空。我在那个位置创建了一个快速的 hello world:

$ docker exec -it test_test_1 /bin/sh
/ # ls -al /data
total 8
drwxr-xr-x    2 root     root          4096 May 23 01:24 .
drwxr-xr-x    1 root     root          4096 May 23 01:24 ..
/ # echo "hello volume" >/data/hello.txt
/ # ls -al /data
total 12
drwxr-xr-x    2 root     root          4096 May 23 01:24 .
drwxr-xr-x    1 root     root          4096 May 23 01:24 ..
-rw-r--r--    1 root     root            13 May 23 01:24 hello.txt
/ # cat /data/hello.txt
hello volume
/ # exit

该卷在 docker 外部可见,并且在 docker-compose down 之后仍然存在:

$ docker volume ls | grep test_
local               test_data

$ docker-compose -f docker-compose.vol-named.yml down
Stopping test_test_1 ... done
Removing test_test_1 ... done
Removing network test_default

$ docker volume ls | grep test_
local               test_data

使用旧卷重新创建容器,其中文件仍然可见:

$ docker-compose -f docker-compose.vol-named.yml up -d
Creating network "test_default" with the default driver
Creating test_test_1

$ docker exec -it test_test_1 /bin/sh
/ # cat /data/hello.txt
hello volume
/ # exit

运行docker-compose down -v 最终会删除容器和卷:

$ docker-compose -f docker-compose.vol-named.yml down -v
Stopping test_test_1 ... done
Removing test_test_1 ... done
Removing network test_default
Removing volume test_data

$ docker volume ls | grep test_

$

如果您发现只有在使用停止/启动而不是向下/向上时才会保留数据,那么您的数据将存储在容器(或可能是匿名卷)中,而不是您的命名卷中,并且容器不是持久的。确保容器内数据的位置正确以避免这种情况。

要调试数据在容器中的存储位置,我建议在容器上使用docker diff。这将显示在该容器内创建、修改或删除的所有文件,这些文件在容器被删除时将丢失。例如:

$ docker run --name test-diff busybox \
  /bin/sh -c "echo hello docker >/etc/hello.conf"

$ docker diff test-diff
C /etc
A /etc/hello.conf

【讨论】:

  • 很好的说明。 +1
  • 数据“在容器中”而不是卷意味着什么?我假设存储在映射到卷的目录中的任何内容都会在卷中?
  • 是的,但是正如 OP 所示,如果您没有将卷映射到正确的位置,则您的数据不在卷中,而是在容器的 RW 层中。当您删除容器时,对该容器(主要是 RW 文件系统层)所做的所有未存储在卷中的更改都会丢失。
  • @BMitch "如果你发现你的数据只有在你使用停止/启动而不是向下/向上时才被持久化,那么你的数据被存储在容器而不是卷中,并且容器不是持久的。”我不确定这是不是真的。如果您依赖于匿名卷(如在 Dockerfile 中定义的卷),那么当您从映像创建新容器时(通过在 docker-compose down 后调用 docker-compose up),您将获得一个新卷。
  • 我同意VOLUME不应该在Dockerfile中使用的想法,但不幸的是许多官方Dockerfile都使用它,包括memsqlmongo
【解决方案2】:

您正在使用docker-compose down,如果您查看文档here

停止容器并移除容器、网络、卷和映像 由up 创建。默认只移除容器和网络。

你是对的,它不应该删除卷(默认情况下)。这可能是一个错误,或者您可能更改了默认配置。但我认为适合您的命令是docker-compose stop。我会尝试用更简单的情况为down 命令做一些测试。

【讨论】:

  • 我正在使用默认配置中的所有内容。我不是 Docker 专家,所以我希望选择合理的默认值;)昨天安装了 Toolbox,所以一切都应该是最新版本:docker-compose 版本 1.6.0,build d99cad6,docker-py 版本:1.7.0。
  • 您是否已经尝试单独构建并运行您的memsqldata,在您的卷中提供一些文件,然后停止它/删除容器并查看是否还有文件?
  • 是的。几天来,我一直在测试相同的 memsql 结构。我刚刚测试过,如果我执行 docker-compose stop,它也可以工作。 down 的行为似乎与预期不同。
  • 我明天会尝试使用版本 2 docker-compose,我会给出一些反馈。但目前,在第一个版本中,没关系,仍然在这里工作。
  • 我按照我所说的使用版本 2 docker-compose 文件进行了尝试。我正在将我的卷安装在主机的目录上。在docker-compose down 之后,不会删除该卷。您的数据库是否真的使用/data 目录来保存您的数据?
【解决方案3】:

这可以追溯到 MemSQL 的错误文档。 memsql/quickstart 容器中的 MemSQL 数据路径是 /memsql 而不是 /var/lib/memsql 就像在独立安装(和 MemSQL 文档中)一样,绝对不是 /data 就像有人告诉我的那样。

【讨论】:

    【解决方案4】:

    不确定这是否有帮助。当您使用docker-compose up -d 时,将下载容器并创建图像。要停止 docker 镜像,请使用 docker-compose down,镜像将保留并可以使用 docker-compose start 重新启动

    我一直在使用向上/向下命令并不断丢失我的数据,直到我尝试停止/启动并且现在数据仍然存在。

    【讨论】:

    • 经过几个小时的搜索,这解决了我的问题!
    • 这是错误的。 docker-compose down 删除卷。我想这就是 Bobby 的意思。
    • 停止/启动将保留相同的容器,如果您从向下/向上丢失数据,那么您不是将数据存储在一个卷中,而是您的数据在容器本身中,这不应该是被认为是持久的。 docker-compose down 不会删除卷,除非您也包含 -v 选项。
    【解决方案5】:

    最简单的解决方案是使用docker-compose stop 而不是docker-compose down。然后docker-compose start重启。

    根据docsdown“停止容器并删除由up创建的容器、网络、卷和图像。”

    【讨论】:

    • docker-compose down 不会删除卷,除非您通过 -v 选项。
    • 这不是我看到的,这个docker-compose.yml 文件。即使没有-v,Down 也肯定会删除该卷。如果有什么我做错了,我很想知道!我害怕意外丢失我的数据库。
    • 这可能值得作为一个包含所有细节的单独问题提出,而不是尝试在 cmets 中进行调试。
    猜你喜欢
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2021-08-19
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多