Docker-compose как правильно установить порядок создания и запуска контейнеров?

Доброго дня уважаемые.
Подскажите как правильно установить порядок билда и запуска контейнеров с помощью docker-compose?
Задача следующая и проблема с ней же.
В процессе создания контейнеров, а именно PostgreSQL, php-fpm, nginx, так же есть необходимость запустить Composer который начинает качать необходимые ему модули, а так же NodeJS с его NPM который тоже тянет модули.
Все это складывается на один Volume в разные папочки, а после окончания закачки Composer-ом еще и запускается миграция бд, которая смотрит в файлик который выкачал композер. После выкачки модулей NPM запускает их билд.
Проблема следующая:
В файле докер композа, я указываю, что первому надо запускаться кконтейнеру с композером который начинает качать файлы, ноя не могу выполнить команду по запуску миграции бд ибо докер думает что у него все ок, он все запустил, контейнер работает пора дальше выполнять сборку и запуск следующего, или же выполнять следующий RUN, а по факту файлы то не сразу выкачиваются, это занимает время, а на большом проекте это занимает до 5 минут и сильно зависит от размера канала на железе где все это стартует. Т.е. нет возможности например выставить слип для ожидания завершения загрузки и уже дальше выполнять стадии.
Тоже самое касается и NPM он тоже запускается, качает, но не нет возможности выполнить билд ибо не все еще скачалось ,а докер думает что все ок, контейнер запущен.
Игрался с
depends_on:
- composer
и пробовал сортировать по разному, один черт, докер считает что контейнер запущен и все ок, но да, он запущен, качает, после завершения закачки, он его тушит и либо внешнем скриптом поднимать контейнер и передавать ему команду на выполнение билда или миграции в случае с бд, но хотелось бы все попробовать решить средствами докера.
Может кто навести на правильные мысли? Как отследить хотя бы когда закончил работать контейнер и использовать это как событие для запуска внешнего скрипта для билда? Думал про мультистейдж билд, но пока я не до конца понимаю как оно рабоатет, да и как там можно решить с тем, что делает докер пока качаются файлы, не думаю что это кардинально поможет.

Если вопросы глупые, не судите строго, я только в процессе изучения докера.

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

апдейт.

решил немного добавить для полноты картины.
Изначально папка куда качает компосер пуста, список чего надо скачать лежит в файле composer.json
папка куда качает NPM тоже пуста, все что надо сказать в нее лежит в файле package.json
После того как все что перечислено в этих файлов скачивается в volume уже можно запускать следующие действия.
файл composer.json и package.json могут меняться и состав чего надо выкачать тоже может меняться.
  • Вопрос задан
  • 1497 просмотров
Пригласить эксперта
Ответы на вопрос 4
Если я правильно понял, сейчас сделано так, что composer начинает свои делишки в запущенном контейнере, а не в процессе билда – создания собственно контейнера.

Кажется, решением было бы создавать собственный image на основе образа composer'а, и подкачивать файлы в процессе построения. А запускать его уже, построенного.

В подпапке ./Composer создать Dockerfile с чем-то подобным:
FROM composer:latest
VOLUME ./data  /data
RUN apt-get update && apt-get install git && git pull trololo && composer install

А в docker-compose.yml
services:
  composer:
    build: ./Composer


Так пока образ билдится, выполняя все что там в Dockerfile, он не считается запущенным, и не стартуют зависимые от него (depends_on) следующие сервисы.
Ответ написан
@k0nart
Посмотрите в сторону https://github.com/jwilder/dockerize. Он умеет ждать когда зависимости будут готовы, работает с разными проколами, в т.ч. file/, можно дождаться когда на докере появится файл Х и тогда начать собирать второй. (ну или по аналогии с другими протоколами, как удобнее)
Ответ написан
fox_12
@fox_12
Расставляю биты, управляю заряженными частицами
Самый простой вариант:
В скрипте старта сервисов в контейнере сделайте примерно такое:

touch /somedir/someflag
... # какая-то продолжительная последовательность инициализации
rm -f /somedir/someflag # это выполнить по успешному окончанию


В другом контейнере который зависит от результатов предыдущего контейнера:
sleep 5   # подождать немного пока основной контейнер инициализируется
while [ -f /somedir/someflag ];
do 
    sleep 1
    echo 'Waiting for container x'
done;
... # старт сервисов зависимого контейнера


Папку /somedir/ должны видеть оба контейнера
Ответ написан
NorthFighter
@NorthFighter Автор вопроса
В процессе решения проблемы выше, столкнулся с необходимостью разместить основную workdir в каталоге выше расположения файла докеркомпоз и рядом лежащих папочек с докерфайлами.
Нарвался на проблему с непониманием путей.
У меня есть скрипт, который клонит проект в папочку, и затем скрипт запускает докер-композ который испольузет в ямле пути к каталогу до склониного проекта.
Сам проект лежит на пару папок выше в каталоге относительно файла докеркомпоза.
В общем в процессе выполнения докеркомпоз ругается что путь должен быть относительным и что как я понимаю конструкции типа ./../project_app не катит.
Придется задавать значения через ENV?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы