Условно монтировать тома в docker-compose для нескольких условий - PullRequest
2 голосов
/ 11 июля 2019

Я использую docker и docker compose для упаковки научных инструментов в легко / универсально исполняемые модули.Одним из примеров является докер, который упаковывает довольно сложную библиотеку Python в контейнер, в котором работает сервер ноутбука Jupyter;Идея состоит в том, что другие ученые, которые не очень разбираются в технологиях, могут клонировать репозиторий github, запустить docker-compose up, а затем выполнить их анализ без необходимости устанавливать библиотеку, настраивать различные плагины и другие зависимости и т. д.

Iу меня все это работает нормально, за исключением того, что у меня проблемы с настройкой громкостных креплений.Причина этого заключается в том, что библиотека внутри контейнера Docker обрабатывает несколько видов наборов данных, которые пользователи будут хранить в нескольких отдельных каталогах, которые обычно отслеживаются с помощью переменных среды оболочки.(Пожалуйста, не говорите мне, что это плохой способ сделать это - это то, как все делается на месте, а не то, как я решил это делать.) Так, например, если пользователь хранит данные FreeSurferони будут иметь переменную окружения с именем SUBJECTS_DIR, которая указывает на каталог, содержащий данные;если они хранят данные HCP, у них будет переменная окружения HCP_SUBJECTS_DIR.Тем не менее, они могут иметь оба, или ни один из этих наборов (а также несколько других).

Я хотел бы иметь возможность поместить что-то подобное в мой файл docker-compose.yml по порядкудля обработки этих случаев:

version: '3'
services:
   my_fancy_library:
      build: .
      ports:
         - "8080:8888"
      environment:
         - HCP_SUBJECTS_DIR="/hcp_subjects"
         - SUBJECTS_DIR="/freesurfer_subjects"
      volumes:
         - "$SUBJECTS_DIR:/freesurfer_subjects"
         - "$HCP_SUBJECTS_DIR:/hcp_subjects"

При тестировании этого, если у пользователя установлены обе переменные окружения, все работает плавноОднако, если у них нет ни одного из этих наборов, я получаю сообщение об ошибке не монтирования каталогов длиной менее 2 символов (что я воспринимаю как жалобу на монтирование тома, указанного в «: / hcp_subjects»).

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

  • Этот инструмент предназначен для использования людьми, которые не обязательно знают что-либо о docker, docker-compose или связанных утилитахпоэтому ожидать, что они напишут / отредактируют свой собственный файл docker-compose.yml, проблема
  • Существует более двух таких каталогов (я показал два в качестве примера), и я не могу реально создатьфайл docker-compose для каждой возможной комбинации этих путей, объявленных или не объявленных
  • Честно говоря, это решение кажется действительно неуклюжим, учитывая, что необходимая информация находится прямо в переменных, которые docker-compose уже читает.

Единственное достойное решение, которое мне удалось найти, - попросить пользователей запустить скрипт ./run.sh вместо docker-compose up;скрипт проверяет переменные окружения, записывает собственный файл docker-compose.yml с соответствующими томами и запускает сам docker-compose up.Это также кажется несколько неуклюжим, но это работает.

Кто-нибудь знает способ условного монтирования набора томов на основе состояния переменных среды при запуске docker-compose up?

Заранее спасибо.

1 Ответ

2 голосов
/ 12 июля 2019

Вы можете установить значения по умолчанию для переменной среды в .env -файле, поставляемом вместе с docker-compose.yml [1] .

Установив для переменных среды значение /dev/null с помощьюпо умолчанию, а затем обрабатывая этот случай в контейнеризованном приложении, вы сможете достичь того, что вам нужно.

Пример

$ tree -a
.
├── docker-compose.yml
├── Dockerfile
├── .env
└── run.sh

docker-compose.yml

version: "3"

services:
  test:
    build: .
    environment:
      - VOL_DST=${VOL_DST}
    volumes:
      - "${VOL_SRC}:${VOL_DST}"

Dockerfile

FROM alpine
COPY run.sh /run.sh
ENTRYPOINT ["/run.sh"]

.env

VOL_SRC=/dev/null
VOL_DST=/volume

run.sh

#!/usr/bin/env sh
set -euo pipefail

if [ ! -d ${VOL_DST} ]; then
  echo "${VOL_DST} not mounted"
else
  echo "${VOL_DST} mounted"
fi

Тестирование

Переменная среды VOL_SRC не определена:

$ docker-compose up
Starting test_test_1 ... done
Attaching to test_test_1
test_1  | /volume not mounted
test_test_1 exited with code 0

Переменная среды VOL_SRC определена:

$ VOL_SRC="./" docker-compose up
Recreating test_test_1 ... done
Attaching to test_test_1
test_1  | /volume mounted

[1] https://docs.docker.com/compose/environment-variables/#the-env-file

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...