今天是个好日子。
我在这里的任务是使用一些将在多个服务之间共享的卷。该卷将由某些服务Dockerfile中的ADD
或COPY
命令填充。我遇到的问题是,通过docker-compose up
启动服务时,卷没有得到更新。
考虑以下设置:
# docker-compose.yml
version: "3"
services:
service-a:
build:
context: service-a
dockerfile: Dockerfile
volumes:
- shared:/test/dir
service-b:
build:
context: service-b
dockerfile: Dockerfile
volumes:
- shared:/another-test/dir
volumes:
shared:
# ./service-a/Dockerfile
FROM alpine:3.8
COPY test-dir /test/dir
CMD [ "tail", "-f", "/dev/null" ]
# ./service-b/Dockerfile
FROM alpine:3.8
CMD [ "tail", "-f", "/dev/null" ]
然后我们将创建
./service-a/test-dir
文件夹。现在,我们来构建它:> docker-compose build
Building service-a
Step 1/3 : FROM alpine:3.8
---> 196d12cf6ab1
Step 2/3 : COPY test-dir /test/dir
---> ac66ed92b442
Step 3/3 : CMD [ "tail", "-f", "/dev/null" ]
---> Running in 932eb32b6184
Removing intermediate container 932eb32b6184
---> 7e0385d17f96
Successfully built 7e0385d17f96
Successfully tagged docker-compose-test_service-a:latest
Building service-b
Step 1/2 : FROM alpine:3.8
---> 196d12cf6ab1
Step 2/2 : CMD [ "tail", "-f", "/dev/null" ]
---> Running in 59a8b91c6b2d
Removing intermediate container 59a8b91c6b2d
---> 4e2c16ea5a80
Successfully built 4e2c16ea5a80
Successfully tagged docker-compose-test_service-b:latest
并启动服务:
> docker-compose up --no-build -d
Creating network "docker-compose-test_default" with the default driver
Creating volume "docker-compose-test_shared" with default driver
Creating docker-compose-test_service-a_1 ... done
Creating docker-compose-test_service-b_1 ... done
让我们检查映射目录:
> docker-compose exec service-a ls -lah /test/dir
total 8
drwxr-xr-x 2 root root 4.0K Dec 12 06:14 .
drwxr-xr-x 3 root root 4.0K Dec 12 06:14 ..
> docker-compose exec service-b ls -lah /another-test/dir
total 8
drwxr-xr-x 2 root root 4.0K Dec 12 06:14 .
drwxr-xr-x 3 root root 4.0K Dec 12 06:14 ..
现在,让我们在主机上的
./service-a/test-dir
中放入几个文本文件,然后重新构建:> docker-compose build
Building service-a
Step 1/3 : FROM alpine:3.8
---> 196d12cf6ab1
Step 2/3 : COPY test-dir /test/dir
---> bd168b0fc8cc
Step 3/3 : CMD [ "tail", "-f", "/dev/null" ]
---> Running in 6e81b32243e1
Removing intermediate container 6e81b32243e1
---> cc28fc6de9ac
Successfully built cc28fc6de9ac
Successfully tagged docker-compose-test_service-a:latest
Building service-b
Step 1/2 : FROM alpine:3.8
---> 196d12cf6ab1
Step 2/2 : CMD [ "tail", "-f", "/dev/null" ]
---> Using cache
---> 4e2c16ea5a80
Successfully built 4e2c16ea5a80
Successfully tagged docker-compose-test_service-b:latest
如您所见,
COPY
中的service-a
步骤未使用缓存,这意味着更改被烘焙到图像中。现在开始服务:> docker-compose up --no-build -d
Recreating docker-compose-test_service-a_1 ...
Recreating docker-compose-test_service-a_1 ... done
service-b
再次保持不变,仅service-a
被重新创建。让我们检查实际的服务(这是发生问题的地方):> docker-compose exec service-a ls -lah /test/dir
total 8
drwxr-xr-x 2 root root 4.0K Dec 12 06:17 .
drwxr-xr-x 3 root root 4.0K Dec 12 06:20 ..
> docker-compose exec service-b ls -lah /another-test/dir
total 8
drwxr-xr-x 2 root root 4.0K Dec 12 06:17 .
drwxr-xr-x 3 root root 4.0K Dec 12 06:14 ..
因此文件不会被反射(reflect)...但是,如果我们根据
service-a
图像启动临时容器,它将显示正确的列表:> docker run --rm docker-compose-test_service-a ls -lah /test/dir
total 8
drwxr-xr-x 2 root root 4.0K Dec 12 06:20 .
drwxr-xr-x 3 root root 4.0K Dec 12 06:20 ..
-rwxr-xr-x 1 root root 0 Dec 12 06:20 rrrrrr.txt
-rwxr-xr-x 1 root root 0 Dec 12 06:16 test.txt
有什么解决方法的想法吗?到目前为止,似乎只有通过
docker-compose down
完全关闭并进行卷销毁才有帮助。虽然不是最佳解决方案,但与真实项目一样,它会导致严重的停机时间。我希望配置是可读的,但是如果需要,我可以将其放入小型git repo中。
提前致谢。
最佳答案
Docker只会auto-populate a volume when it is first created。在您描述的工作流程中,当删除并重新创建带有其新镜像的“第一个”容器时,您也需要删除并重新创建该卷,这可能意味着删除并重新创建整个堆栈。
有两种方法可以解决此问题:
#!/bin/sh
# Run me as the image's ENTRYPOINT.
if [ -d /data ]; then
cp -r /app/static /data
done
exec "$@"
这将在每次启动时重新填充数据量。
关于docker - docker-compose没有在共享卷中获取文件系统更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53737268/