docker-compose文件之间的共享卷

时间:2020-11-09 12:21:58

标签: docker docker-compose volumes

我想在2个docker-compose文件之间共享一个卷。有2个相互关联的应用程序,我需要在它们之间创建符号链接。 我尝试使用命名卷和外部功能。

在第一个容器上,我可以看到/ var / www / s1文件夹的内容,但是/ var / www / s2文件夹是空的,而在第二个容器上,我可以看到/ var /的内容www / s2文件夹,但/ var / www / s1文件夹似乎为空。由于在/ var / www中看不到其他应用程序创建的文件夹的内容,因此无法进行符号链接。

我制作了一些虚拟的docker-compose文件,以尝试以更简单的方式揭示问题。

在/ var / www / s1中应该有一个“ magazine.txt”文件,而在/ var / www / s2中应该有一个“ paper.txt”文件。

第一个docker-compose文件如下:

services:
  nginx:
    image: nginx
    container_name: nginx
    volumes:
      - ../:/var/www/s1
      - shared-s:/var/www
volumes:
  shared-s:
    name: shared-s

第二个docker-compose文件如下:

version: '3.8'
services:
  php:
    image: php
    container_name: php
    command: tail -F /var/www/s2/paper.txt
    volumes:
      - ../:/var/www/s2
      - shared-s:/var/www
volumes:
  shared-s:
    external:
      name: shared-s
$ docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                              NAMES
80b83a60a0e5        php                   "docker-php-entrypoi…"   2 seconds ago       Up 1 second                                            php
05addf1fc24e        nginx                 "/docker-entrypoint.…"   9 seconds ago       Up 8 seconds        80/tcp                             nginx
8c596d21cf7b        portainer/portainer   "/portainer"             2 hours ago         Up About a minute   9000/tcp, 0.0.0.0:9001->9001/tcp   portainer

$ docker exec -it 05addf1fc24e sh
# cd /var/www
# ls
s1  s2
# cd s1
# ls
docker  magazine.txt
# cd ..
# cd s2
# ls
# exit
$ docker exec -it 80b83a60a0e5 sh
# cd /var/www
# ls
s1  s2
# cd s1
# ls
# cd ..
# cd s2
# ls
docker  paper.txt
# exit

1 个答案:

答案 0 :(得分:1)

在机械层面上,卷和装订座不会像您建议的那样“嵌套”。命名的卷shared-s将只包含 个空目录s1s2,但两个主机目录中的内容都不包含。

发生的事情是这样的:

  1. Docker首先启动(说)nginx容器。它将volumes:容器上的安装座从最短到最长排序。
  2. 由于shared-s卷为空,因此nginx/var/www基本映像的内容被复制到该卷;然后将卷安装在容器中的/var/www上。
  3. Docker在卷中创建挂载点/var/www/s1,然后在其中绑定-挂载主机目录(根本无需修改卷)。
  4. Docker启动php容器并对其volumes:进行排序。
  5. 由于shared-s卷不为空,因此Docker只是将其安装到容器中,隐藏了图像中/var/www中可能存在的所有内容。
  6. Docker在卷中创建挂载点/var/www/s2,然后在其中绑定-挂载主机目录(根本无需修改卷)。

您会发现此序列存在一些问题。其他装入的卷的内容永远不会复制到“共享”卷中,这会破坏您在此处尝试进行的文件共享。无论哪个容器启动,都首先将内容从其映像复制到共享卷中,而另一个容器中该映像中的任何内容都会丢失。因此,如果基础映像中有更新,则Docker将忽略该更新,而使用共享卷中的(旧)内容。

我建议完全避免此处的卷。为每个容器构建一个单独的映像,COPY将应用程序代码插入其中。如果可以在后端应用程序中使用静态文件服务器,则比将文件从一个容器复制到另一个容器要容易得多。如果无法避免,则可以使用多阶段构建中通常使用的COPY --from=image语法,也可以将内容从一个构建的映像复制到另一个。