docker-compose 安装的卷是空的,但在 Docker 映像构建期间创建的其他卷被填充
docker-compose mounted volume is empty, but other volumes created during Docker image build are populated
从一个空目录开始,我创建了这个 docker-compose.yml
:
version: '3.9'
services:
neo4j:
image: neo4j:3.2
restart: unless-stopped
ports:
- 7474:7474
- 7687:7687
volumes:
- ./conf:/conf
- ./data:/data
- ./import:/import
- ./logs:/logs
- ./plugins:/plugins
environment:
# Raise memory limits
- NEO4J_dbms_memory_pagecache_size=1G
- NEO4J_dbms.memory.heap.initial_size=1G
- NEO4J_dbms_memory_heap_max__size=1G
然后我添加 import
目录,其中包含我打算在容器中使用的数据文件。
此时,我的目录如下所示:
0 drwxr-xr-x 9 cc staff 288 Dec 11 18:57 .
0 drwxr-xr-x 5 cc staff 160 Dec 11 18:15 ..
8 -rw-r--r-- 1 cc staff 458 Dec 11 18:45 docker-compose.yml
0 drwxr-xr-x 20 cc staff 640 Dec 11 18:57 import
I 运行 docker-compose up -d --build
,容器构建完成。现在本地目录如下所示:
0 drwxr-xr-x 9 cc staff 288 Dec 11 18:57 .
0 drwxr-xr-x 5 cc staff 160 Dec 11 18:15 ..
0 drwxr-xr-x 2 cc staff 64 Dec 11 13:59 conf
0 drwxrwxrwx@ 4 cc staff 128 Dec 11 18:08 data
8 -rw-r--r-- 1 cc staff 458 Dec 11 18:45 docker-compose.yml
0 drwxr-xr-x 20 cc staff 640 Dec 11 18:57 import
0 drwxrwxrwx@ 3 cc staff 96 Dec 11 13:59 logs
0 drwxr-xr-x 3 cc staff 96 Dec 11 15:32 plugins
已创建 conf
、data
、logs
和 plugins
目录。
data
和 logs
是从 Neo4j 图像的构建中填充的,并且 conf
和 plugins
是空的,正如预期的那样。
我用docker exec
查看容器上的目录结构:
8 drwx------ 1 neo4j neo4j 4096 Dec 11 23:46 .
8 drwxr-xr-x 1 root root 4096 May 11 2019 ..
36 -rwxrwxrwx 1 neo4j neo4j 36005 Feb 18 2019 LICENSE.txt
128 -rwxrwxrwx 1 neo4j neo4j 130044 Feb 18 2019 LICENSES.txt
12 -rwxrwxrwx 1 neo4j neo4j 8493 Feb 18 2019 NOTICE.txt
4 -rwxrwxrwx 1 neo4j neo4j 1594 Feb 18 2019 README.txt
4 -rwxrwxrwx 1 neo4j neo4j 96 Feb 18 2019 UPGRADE.txt
8 drwx------ 1 neo4j neo4j 4096 May 11 2019 bin
4 drwxr-xr-x 2 neo4j neo4j 4096 Dec 11 23:46 certificates
8 drwx------ 1 neo4j neo4j 4096 Dec 11 23:46 conf
0 lrwxrwxrwx 1 root root 5 May 11 2019 data -> /data
4 drwx------ 1 neo4j neo4j 4096 Feb 18 2019 import
8 drwx------ 1 neo4j neo4j 4096 May 11 2019 lib
0 lrwxrwxrwx 1 root root 5 May 11 2019 logs -> /logs
4 drwx------ 1 neo4j neo4j 4096 Feb 18 2019 plugins
4 drwx------ 1 neo4j neo4j 4096 Feb 18 2019 run
我的问题是容器中的import
目录是空的。 data
和 logs
目录不是空的。
我本地的 data
和 logs
目录具有 conf
和 plugins
没有的扩展属性:
xattr -l data
com.docker.grpcfuse.ownership: {"UID":100,"GID":101}
我能识别的唯一区别是那些目录包含 docker-compose
在抓取 Neo4j 图像时创建的数据。
有谁知道这里发生了什么,并告诉我如何让它工作?我正在使用 Mac OS X 10.15 和 docker-compose 版本 1.27.4,构建 40524192.
谢谢。
TL;DR:您当前的设置可能工作正常。
了解您观察到的具体行为:
在容器启动时,Docker 将在主机上创建空目录(如果它们不存在),并在容器内创建挂载点目录。 (这就是出现这些目录的原因。)
Docker 从不 将图像中的数据复制到绑定装载中。此行为仅发生在命名卷上(并且仅在您第一次使用它们时发生,不会在以后运行时发生;并且仅在本机 Docker 上发生,而不会在 Kubernetes 上发生)。
但是,标准数据库图像通常知道如何初始化一个空数据目录。在 neo4j
image, its Dockerfile ends with an ENTRYPOINT
directive that runs at container startup; that docker-entrypoint.sh
的情况下,知道如何进行各种首次设置。这就是数据进入 ./data
.
的方式
图像还声明了一个 WORKDIR /var/lib/neo4j
(通过中间环境变量)。这就解释了,在您的 ls -l
列表中,为什么会有像 data -> /data
这样的符号链接。您的绑定挂载是 /import
,但如果您 docker-compose exec neo4j ls import
,它将看起来相对于 WORKDIR
,这就是为什么目录看起来是空的。
但是,entrypoint脚本专门在容器内部寻找/import
目录,如果存在且可读,则设置环境变量NEO4J_dbms_directories_import=/import
.
这一切都向我表明您的设置是正确的,如果您尝试执行导入,它将正常工作并看到您的主机数据。您正在查看映像中的 /var/lib/neo4j/import
目录,它是空的,但映像启动知道还要在容器中查找 /import
,并且您的挂载点在那里。
从一个空目录开始,我创建了这个 docker-compose.yml
:
version: '3.9'
services:
neo4j:
image: neo4j:3.2
restart: unless-stopped
ports:
- 7474:7474
- 7687:7687
volumes:
- ./conf:/conf
- ./data:/data
- ./import:/import
- ./logs:/logs
- ./plugins:/plugins
environment:
# Raise memory limits
- NEO4J_dbms_memory_pagecache_size=1G
- NEO4J_dbms.memory.heap.initial_size=1G
- NEO4J_dbms_memory_heap_max__size=1G
然后我添加 import
目录,其中包含我打算在容器中使用的数据文件。
此时,我的目录如下所示:
0 drwxr-xr-x 9 cc staff 288 Dec 11 18:57 .
0 drwxr-xr-x 5 cc staff 160 Dec 11 18:15 ..
8 -rw-r--r-- 1 cc staff 458 Dec 11 18:45 docker-compose.yml
0 drwxr-xr-x 20 cc staff 640 Dec 11 18:57 import
I 运行 docker-compose up -d --build
,容器构建完成。现在本地目录如下所示:
0 drwxr-xr-x 9 cc staff 288 Dec 11 18:57 .
0 drwxr-xr-x 5 cc staff 160 Dec 11 18:15 ..
0 drwxr-xr-x 2 cc staff 64 Dec 11 13:59 conf
0 drwxrwxrwx@ 4 cc staff 128 Dec 11 18:08 data
8 -rw-r--r-- 1 cc staff 458 Dec 11 18:45 docker-compose.yml
0 drwxr-xr-x 20 cc staff 640 Dec 11 18:57 import
0 drwxrwxrwx@ 3 cc staff 96 Dec 11 13:59 logs
0 drwxr-xr-x 3 cc staff 96 Dec 11 15:32 plugins
已创建 conf
、data
、logs
和 plugins
目录。
data
和 logs
是从 Neo4j 图像的构建中填充的,并且 conf
和 plugins
是空的,正如预期的那样。
我用docker exec
查看容器上的目录结构:
8 drwx------ 1 neo4j neo4j 4096 Dec 11 23:46 .
8 drwxr-xr-x 1 root root 4096 May 11 2019 ..
36 -rwxrwxrwx 1 neo4j neo4j 36005 Feb 18 2019 LICENSE.txt
128 -rwxrwxrwx 1 neo4j neo4j 130044 Feb 18 2019 LICENSES.txt
12 -rwxrwxrwx 1 neo4j neo4j 8493 Feb 18 2019 NOTICE.txt
4 -rwxrwxrwx 1 neo4j neo4j 1594 Feb 18 2019 README.txt
4 -rwxrwxrwx 1 neo4j neo4j 96 Feb 18 2019 UPGRADE.txt
8 drwx------ 1 neo4j neo4j 4096 May 11 2019 bin
4 drwxr-xr-x 2 neo4j neo4j 4096 Dec 11 23:46 certificates
8 drwx------ 1 neo4j neo4j 4096 Dec 11 23:46 conf
0 lrwxrwxrwx 1 root root 5 May 11 2019 data -> /data
4 drwx------ 1 neo4j neo4j 4096 Feb 18 2019 import
8 drwx------ 1 neo4j neo4j 4096 May 11 2019 lib
0 lrwxrwxrwx 1 root root 5 May 11 2019 logs -> /logs
4 drwx------ 1 neo4j neo4j 4096 Feb 18 2019 plugins
4 drwx------ 1 neo4j neo4j 4096 Feb 18 2019 run
我的问题是容器中的import
目录是空的。 data
和 logs
目录不是空的。
我本地的 data
和 logs
目录具有 conf
和 plugins
没有的扩展属性:
xattr -l data
com.docker.grpcfuse.ownership: {"UID":100,"GID":101}
我能识别的唯一区别是那些目录包含 docker-compose
在抓取 Neo4j 图像时创建的数据。
有谁知道这里发生了什么,并告诉我如何让它工作?我正在使用 Mac OS X 10.15 和 docker-compose 版本 1.27.4,构建 40524192.
谢谢。
TL;DR:您当前的设置可能工作正常。
了解您观察到的具体行为:
在容器启动时,Docker 将在主机上创建空目录(如果它们不存在),并在容器内创建挂载点目录。 (这就是出现这些目录的原因。)
Docker 从不 将图像中的数据复制到绑定装载中。此行为仅发生在命名卷上(并且仅在您第一次使用它们时发生,不会在以后运行时发生;并且仅在本机 Docker 上发生,而不会在 Kubernetes 上发生)。
但是,标准数据库图像通常知道如何初始化一个空数据目录。在
的方式neo4j
image, its Dockerfile ends with anENTRYPOINT
directive that runs at container startup; thatdocker-entrypoint.sh
的情况下,知道如何进行各种首次设置。这就是数据进入./data
.图像还声明了一个
WORKDIR /var/lib/neo4j
(通过中间环境变量)。这就解释了,在您的ls -l
列表中,为什么会有像data -> /data
这样的符号链接。您的绑定挂载是/import
,但如果您docker-compose exec neo4j ls import
,它将看起来相对于WORKDIR
,这就是为什么目录看起来是空的。但是,entrypoint脚本专门在容器内部寻找
/import
目录,如果存在且可读,则设置环境变量NEO4J_dbms_directories_import=/import
.
这一切都向我表明您的设置是正确的,如果您尝试执行导入,它将正常工作并看到您的主机数据。您正在查看映像中的 /var/lib/neo4j/import
目录,它是空的,但映像启动知道还要在容器中查找 /import
,并且您的挂载点在那里。