Общий том между файлами docker-compose

#docker #docker-compose #volumes

#docker #docker-compose #тома

Вопрос:

Я хочу разделить объем между 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:

На механическом уровне тома и привязки монтируются не так, как вы предлагаете. Именованный том shared-s будет содержать только пустые каталоги s1 и s2 , но не содержимое ни из одного из каталогов хоста.

Что происходит, это что-то вроде этого:

  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 синтаксис, который обычно используется при многоэтапных сборках, чтобы также копировать содержимое из одного созданного образа в другой.