如何使用 Docker Compose v2 使卷永久化
How to make volumes permanent with Docker Compose v2
我知道其他人也有类似的问题,但这使用 v2 撰写文件格式,我没有找到任何相关的东西。
我想制作一个非常简单的测试应用程序来使用 MemSQL,但我无法让卷在 docker-compose down
之后不被删除。如果我对 Docker 文档的理解是正确的,那么在没有明确告知的情况下不应删除卷。一切似乎都适用于 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
您正在使用 docker-compose down
如果您查看文档 here
Stop containers and remove containers, networks, volumes, and images
created by up
. Only containers and networks are removed by default.
你是对的,它不应该删除卷(默认情况下)。这可能是一个错误,或者您可能更改了默认配置。但我认为适合您的命令是 docker-compose stop
。我将尝试用更简单的案例对 down
命令进行一些测试。
这可以追溯到 MemSQL 的错误文档。 memsql/quickstart
容器中的 MemSQL 数据路径是 /memsql
,而不是像独立安装(和 MemSQL 文档中)那样的 /var/lib/memsql
,绝对不是有人告诉我的 /data
。
不确定这是否有帮助。当您使用 docker-compose up -d
时,将下载容器并创建图像。要停止 docker 图像,请使用 docker-compose down
,图像将保留并可以使用 docker-compose start
重新启动
我一直在使用 up/down 命令并不断丢失我的数据,直到我尝试 stop/start 并且现在数据仍然存在。
最简单的解决方案是使用 docker-compose stop
而不是 docker-compose down
。然后docker-compose start
重启。
根据 docs、down
"stops containers and removes containers, networks, volumes, and images created by up."
我意识到这是一个旧的且已解决的线程,其中 OP 指向容器中的目录而不是它们安装的卷,但我想清除我看到的一些错误信息。
docker-compose down
不会删除卷,如果您还想删除卷,则需要 运行 docker-compose down -v
。这是直接来自 docker-compose 的帮助文本(注意 "by default" 列表):
$ 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
启动容器后,卷初始化为空,因为该位置的图像是空的。我在该位置创建了一个快速问候世界:
$ 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_
$
如果您发现您的数据仅在您使用 stop/start 而不是 down/up 时才被持久化,那么您的数据将存储在容器(或可能是匿名卷)中而不是您的命名卷,并且容器不是持久的。确保您的数据在容器内的位置正确以避免这种情况。
要调试数据在容器中的存储位置,我建议在容器上使用 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
我知道其他人也有类似的问题,但这使用 v2 撰写文件格式,我没有找到任何相关的东西。
我想制作一个非常简单的测试应用程序来使用 MemSQL,但我无法让卷在 docker-compose down
之后不被删除。如果我对 Docker 文档的理解是正确的,那么在没有明确告知的情况下不应删除卷。一切似乎都适用于 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
您正在使用 docker-compose down
如果您查看文档 here
Stop containers and remove containers, networks, volumes, and images created by
up
. Only containers and networks are removed by default.
你是对的,它不应该删除卷(默认情况下)。这可能是一个错误,或者您可能更改了默认配置。但我认为适合您的命令是 docker-compose stop
。我将尝试用更简单的案例对 down
命令进行一些测试。
这可以追溯到 MemSQL 的错误文档。 memsql/quickstart
容器中的 MemSQL 数据路径是 /memsql
,而不是像独立安装(和 MemSQL 文档中)那样的 /var/lib/memsql
,绝对不是有人告诉我的 /data
。
不确定这是否有帮助。当您使用 docker-compose up -d
时,将下载容器并创建图像。要停止 docker 图像,请使用 docker-compose down
,图像将保留并可以使用 docker-compose start
我一直在使用 up/down 命令并不断丢失我的数据,直到我尝试 stop/start 并且现在数据仍然存在。
最简单的解决方案是使用 docker-compose stop
而不是 docker-compose down
。然后docker-compose start
重启。
根据 docs、down
"stops containers and removes containers, networks, volumes, and images created by up."
我意识到这是一个旧的且已解决的线程,其中 OP 指向容器中的目录而不是它们安装的卷,但我想清除我看到的一些错误信息。
docker-compose down
不会删除卷,如果您还想删除卷,则需要 运行 docker-compose down -v
。这是直接来自 docker-compose 的帮助文本(注意 "by default" 列表):
$ 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
启动容器后,卷初始化为空,因为该位置的图像是空的。我在该位置创建了一个快速问候世界:
$ 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_
$
如果您发现您的数据仅在您使用 stop/start 而不是 down/up 时才被持久化,那么您的数据将存储在容器(或可能是匿名卷)中而不是您的命名卷,并且容器不是持久的。确保您的数据在容器内的位置正确以避免这种情况。
要调试数据在容器中的存储位置,我建议在容器上使用 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