【问题标题】:Shared volume between docker-compose filesdocker-compose 文件之间的共享卷
【发布时间】:2021-02-21 08:51:11
【问题描述】:

我想在 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

【问题讨论】:

    标签: docker docker-compose volumes


    【解决方案1】:

    在机械层面上,卷和绑定安装不会以您建议的方式“嵌套”。命名卷 shared-s 最终将包含 空目录 s1s2,但没有来自任一主机目录的内容。

    发生的事情是这样的:

    1. Docker 首先启动(比如说)nginx 容器。它将该容器上的 volumes: 挂载从最短到最长排序。
    2. 由于shared-s卷为空,将/var/wwwnginx基础镜像的内容复制到卷中;然后将卷挂载到容器中的/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 语法将内容从一个构建的图像复制到另一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 2018-10-28
      相关资源
      最近更新 更多