Именованные тома Docker между несколькими контейнерами

Я хочу развернуть некоторые сервисы на своем сервере, и все они будут использовать nginx в качестве веб-сервера, каждый проект имеет свой собственный файл .conf, и я хочу поделиться всем этим с контейнером nginx. Я пытался использовать именованные тома, но когда они используются более чем одним контейнером, данные заменяются. Я хочу получить все эти файлы .conf из разных контейнеров и поместить их в том, чтобы он мог быть прочитан контейнером nginx. Я также пытался использовать подкаталоги в именованных томах, но использование namedVolumeName/path не работает.

Obs: я использую docker-compose во всех проектах

version: "3.7"

services:
  backend:
    container_name: jzmimoveis-backend
    image: paulomesquita/jzmimoveis-backend
    command: uwsgi --socket :8000 --wsgi-file jzmimoveis/wsgi.py
    volumes:
      - nginxConfFiles:/app/nginx
      - jzmimoveisFiles:/app/src
    networks:
      - jzmimoveis
    restart: unless-stopped
    expose:
      - 8000

  frontend:
    container_name: jzmimoveis-frontend
    image: paulomesquita/jzmimoveis-frontend
    command: serve -s build/
    volumes:
      - nginxConfFiles:/app/nginx
    networks:
      - jzmimoveis
    restart: unless-stopped
    expose:
      - 5000

volumes:
  nginxConfFiles:
    external: true
  jzmimoveisFiles:
    external: true
networks:
  jzmimoveis:
    external: true

Например, в этом случае я связал внешний и внутренний файлы nginx с именованным томом nginxConfFiles, но когда я делаю docker-compose up -d в этом файле, в томе появляется только один из файлов .conf, я думаю, что он перезаписывается другим контейнером в том же файле.


person Paulo Mesquita    schedule 27.06.2020    source источник
comment
Если вы имеете дело с развертыванием, я вряд ли предлагаю вам использовать контейнерный оркестратор, а не docker-compose (например, использовать K8s или Docker swarm). Теперь по вашему вопросу, не могли бы вы предоставить нам пример кода вашей реализации. Как вы объяснили здесь, немного сложно понять, были ли какие-либо ошибки в реализации...   -  person jossefaz    schedule 28.06.2020


Ответы (2)


Вероятно, вы могли бы иметь в контейнере nginx общий том, указывающий на /etc/nginx/conf.d, а затем использовать разные имена для каждого файла конфигурации проекта.

Ниже доказательство концепции, три сервера с файлом конфигурации, который нужно прикрепить к каждому, и прокси (ваш Nginx) с общим томом, привязанным к /config:

version: '3'

services:
  server1:
    image: busybox:1.31.1
    volumes:
    - deleteme_after_demo:/config
    - ./server1.conf:/app/server1.conf
    command: sh -c "cp /app/server1.conf /config; tail -f /dev/null"

  server2:
    image: busybox:1.31.1
    volumes:
    - deleteme_after_demo:/config
    - ./server2.conf:/app/server2.conf
    command: sh -c "cp /app/server2.conf /config; tail -f /dev/null"

  server3:
    image: busybox:1.31.1
    volumes:
    - deleteme_after_demo:/config
    - ./server3.conf:/app/server3.conf
    command: sh -c "cp /app/server3.conf /config; tail -f /dev/null"

  proxy1:
    image: busybox:1.31.1
    volumes:
    - deleteme_after_demo:/config:ro
    command: tail -f /dev/null

volumes:
  deleteme_after_demo:

Давайте создадим 3 файла конфигурации для включения:

➜ echo "server 1" > server1.conf
➜ echo "server 2" > server2.conf
➜ echo "server 3" > server3.conf

тогда:

➜ docker-compose up -d                  
Creating network "deleteme_default" with the default driver
Creating deleteme_server2_1 ... done
Creating deleteme_server3_1 ... done
Creating deleteme_server1_1 ... done
Creating deleteme_proxy1_1  ... done

И, наконец, давайте проверим, что файлы конфигурации доступны из прокси-контейнера:

➜ docker-compose exec proxy1 sh -c "cat /config/server1.conf"
server 1

➜ docker-compose exec proxy1 sh -c "cat /config/server2.conf"
server 2

➜ docker-compose exec proxy1 sh -c "cat /config/server3.conf"
server 3

Я надеюсь, что это помогает. Ваше здоровье!

Примечание: вы должны увидеть монтирование тома точно так же, как при использовании команды mount Unix. Если у вас уже есть содержимое внутри точки монтирования, то после монтирования вы увидите не его, а содержимое смонтированного устройства (если только оно не было пустым и создано здесь впервые). Все, что вы хотите увидеть, должно быть уже на устройстве или вам нужно переместить его позже.

Итак, я сделал это, смонтировав файлы, потому что у меня не было данных в контейнере, который я использовал. Затем скопируйте их с помощью команды запуска. Вы можете решить эту проблему по-другому, например, скопировав файл конфигурации на подключенный том с помощью сценария точки входа в вашем образе.

person Ictus    schedule 28.06.2020
comment
У них разные имена, но они перезаписываются при инициализации другого контейнера в томе с тем же именем. - person Paulo Mesquita; 29.06.2020
comment
Я обновил свой ответ предложением. Может быть, попытка таким образом применима к вам? - person Ictus; 29.06.2020
comment
Когда я запускаю этот файл, который находится в моем вопросе, том остается только с внутренним файлом, и если я вхожу внутрь контейнера внешнего интерфейса, внутри него находится файл backend.conf. Может потому, что я не привязываю файл .conf к контейнеру, а он там уже есть? Не нашел, что не так с моим файлом - person Paulo Mesquita; 29.06.2020
comment
Это не сработает. Если вы запустите его, вы должны увидеть, что все файлы server*.conf в proxy1 пусты, независимо от того, что находится в каждом из файлов conf, которые вы смонтировали с хоста. Эти файлы являются заглушками файловой системы для монтирования привязки, происходящего в других контейнерах, но эти монтирования привязки зависят от контейнера. Содержимое server1.conf видно только на server1. - person BMitch; 29.06.2020
comment
@BMitch Вы правы ... Спасибо, что указали на это. Я должен был провести более глубокое тестирование. Я обновляю свой пост с правильными изменениями. - person Ictus; 29.06.2020
comment
Теперь я не монтирую его внутри точки монтирования, что не сработало, как показал @BMitch, но в команде контейнера я перемещаю файл конфигурации - person Ictus; 29.06.2020
comment
Да, у вас есть облегченная версия сценария load-volume, опубликованная в моем ответе, но с использованием другого тома в качестве источника. Все это сводится к тому, что для копирования требуется точка входа, поскольку функциональность больше нигде недоступна. - person BMitch; 29.06.2020

Именованный том инициализируется, когда он пустой/новый, и контейнер запускается с использованием этого тома. Инициализация происходит из файловой системы образа, и после этого именованный том становится постоянным и сохраняет состояние от предыдущего использования.

В этом случае у вас есть состояние гонки. Том совместно использует файлы, но это зависит от того, какой контейнер compose запускается первым, чтобы контролировать, какое изображение используется для инициализации тома. Именованный том используется несколькими изображениями, это просто содержимое, которое вы хотите различать.

Для вашего варианта использования вам может быть лучше добавить некоторую логику в сборку образа и точку входа, чтобы сохранить файлы, которые вы хотите отразить в томе, в другом месте в образе при сборке, а затем обновить том при запуске контейнера. Удалив это из шагов инициализации именованного тома, вы избежите состояния гонки и позволите обновлять том будущими изменениями из образа. Примером этого является мой базовый образ с save-volume, который вы запустить в Dockerfile, и load-volume вы запустите в своей точке входа.

В качестве примечания также рекомендуется монтировать этот именованный том как доступный только для чтения в контейнерах, которым не нужно записывать файлы конфигурации.

person BMitch    schedule 28.06.2020