Comments 22
Какая-же боль — такое читать. Вроде давно уже космические киты бороздят просторы амазона, а тут — какие-то обвязочные шелл-скрипты, как в старо-древние времена.
Kubernetes, nomad, ansible, в конце-концов.
А вы, как у меня сложилось впечатление по прочтению — "принятыми соглашениями" превращаете самые простые стейтлесс контейнеры в какой-то ад.
Для параллельной работы над несколькими проектами требуется установка всех сервисов необходимых каждому из них. В первую очередь мы создали репозиторий, в котором располагался файл конфигурации для docker-compose, а также конфигурации требуемых для работы образов. Все довольно быстро заработало и на какое-то время это нас устроило. Как оказалось, в дальнейшем данный подход решал нашу проблему частично. По мере добавления проектов в новую экосистему этот репозиторий наполнялся файлами конфигураций и различными вспомогательными скриптами. Это привело к тому что при работе над одним единственным проектом разработчику приходилось либо тащить зависимости всех проектов, либо же править docker-compose.yml, отключая лишние сервисы. В первом случае приходилось ставить лишние контейнеры, что нам казалось не лучшим решением, а во втором нужно было знать какие контейнеры требуются для работы приложения. Хотелось иметь более гибкое решение, которое позволит устанавливать только необходимые компоненты, а также, если не исключит, то минимизирует ручную работу. И вот к чему мы пришли...
Не совсем понятно, как у вас так получилось. Один проект — один docker-compose файл, разве нет? Или у вас там космическое число микросервисов?
Мы делаем немного подругому.
Есть принципы похожие с вами, но помойму мы гораздо проще решили.
docker-compose.yml поддерживает инклюды.
Опредение сервиса хранится в репе сервиса.
В репе проекта хранится главный docker-compose.yml в котором прописаны инклюды и переопределены порты если пересекаются у сервисов.
Там же через лейблы прописаны гит ссылки на зависимости (репы сервисов).
Простой улилитой (рнр скрипт собраный в один исполняемый файл) https://habrahabr.ru/post/306384/
Подтягиваются зависимости
Ей же билдятся все зависимости (у нас билд приложение и билд имиджа два разных этапа)
Запуск проекта выглядит приблизительно так
git clone git://project
cd project
docker-project update # с этого момента инклюды в проекте становятся действительными
docker-project build # если у вас свой билд процесс
docker-compose up
Из плюсов
1 Минимальный уровень входа
2 Нет дополнительных конфиг файлов
3 Нет влияния на код микросервиса
Из минусов
1 Утилита требует установленного php-cli
(Можно переписать на питон или лучше Го, но пока руки не доходят.)
В репе проекта хранится главный docker-compose.yml
Я правильно поннимаю, что docker-compose запускает сервисы на основе этого файла? Если так, имеется ли воможность поднять окружение для нескольких проектов одновременно?
Через указывание несколько проектов
docker-project update -f pro-a.yml
docker-project update -f pro-b.yml
docker-compose -f pro-a.yml -f pro-b.yml up
Конечно, не так изящно как у вас. У нас как-то нет необходимости так проэкты запускать.
Хотя у нас около сотни своих сервисов (несчитая публичные типа мемкеш, редис, мускуль и т.д.) и 25 проект yml файлов.
docker-compose -f pro-a.yml -f pro-b.yml up
Мы от подобного старались уйти, так как параллельная работа нескольких проектов была для нас важным пунктом.
Сейчас заметил v3 инклюды не поддерживает пока.
Для v3 все выше так же справедливо, однако определение сервиса придется хранить в определении проекта.
Вы эту проблему решили генерацией конфига, как я понимаю.
Например, включение разработчика в новый проект может заключаться в git clone (с простейшей оберткой, если не хочется писать полный URL), echo 127.0.0.1 my.project.ddk >> /etc/hosts, docker-compose up -d. За запуск всего окружения отвечает docker-compose, поэтому фактически ddk расширяет его (тот же post-install скрипт — это настройка ENV переменных для докера). Я бы, на вскидку, просто копировал docker-compose из проекта в проект. Возможно, написал бы генерилку для него из каких-то параметров. Как раз интересно понять почему отказались от такого пути и перешли на текущую схему, насколько это частное/общее решение.
Ощущение, что очень частное.
У нас я использую docker-compose.yml в корне проекта для общего описания проекта. docker-compose.override.yml.dist и .env.dist с дефолтными настройками разработчика, которые каждый разработчик затачивает под свои нужды. Плюс docker-compose-stack.yml для docker stack deploy --compose-file docker-compose.yml --compose-file docker-compose-stack.ym (в теории, на практике приходится предварительно мержить файлы через docker-compose config --file docker-compose.yml --file docker-compose-stack.ym).
Пока единственный недостаток значимый — при одновременной работе над двумя версиями проекта, которые отличаются от мастера лишь парой контейнеров (провайдер и клиент какого-нить API, например) из пары-тройки десятков, остальные разворачиваются в двух экземплярах. Пробовал разные решения, более-менее приемлемые нашёл только если одновременная работа затрагивает лишь один контейнер, причём заведомо (до docker-compose up) известный какой. Если их несколько, то да, думаю о написании генерилки, которая будет генерить docker-compose.yml по результатам git diff --names-only master так, чтобы шарились контейнеры из мастера через external_links, а то и вообще "bare metal" сервисы через external_hosts, как у нас шарятся в продакшене statefull сервисы не под докером вообще.
Ну у нас почти то же самое: git clone; cp .dist ; docker-compose up; — запустится всё необходимое окружение локально, со смонтированными каталогами типа src. Вернее пока только наши сервисы и стандартные, в перспективе заглушки для внешних партнерских.
Проблемы с этим сценарием в основном у тех, кому хочется странного, типа одновременно держать две версии проекта в соседних окнах браузера с шарящимися 90% контейнеров.
Простое копирование конфигурационных файлов затрудняет их модификацию в дальнейшем. Если понадобится внести изменения в какой-либо контейнер, придется пройтись по всем проектам, которые его используют.
Кажется понял вашу особенность: у вас контейнеры шарятся между разными проектами, а не между разными версиями одного проекта. Сходу могу придумать как обойти если набор таких сервисов фиксирован и все проекты должны работать с одной версией. А вот если иногда нужно для отдельного проекта запустить свою версию конкретного "общего" контейнера, а другим оставить общую, да в одном экземпляре — тут не уверен, что чисто стандартными докеровскими инструментами можно обойтись без хитрых игр с башем или ещё чем.
Когда docker-compose не хватает