Compose: Выполнить команду после запуска

Созданный на 5 авг. 2015  ·  131Комментарии  ·  Источник: docker/compose

Привет,

Было бы очень полезно иметь что-то вроде «onrun» в YAML, чтобы иметь возможность запускать команды после запуска. Аналогично https://github.com/docker/docker/issues/8860

mongodb:
    image: mongo:3.0.2
    hostname: myhostname
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 
    onrun:
        - mongodump --host db2dump.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

После запуска mongodb он сбросит db2dump.domain.lan и восстановит его.

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

ИЗМЕНИТЬ 15 июня 2020 г.

5 лет спустя Compose не стал "стандартизировать" спецификации,
пожалуйста, проверьте https://github.com/compose-spec/compose-spec/issues/84

Самый полезный комментарий

Итак, чтобы управлять моим докером, вы предлагаете мне использовать скрипт или Makefile. Итак, почему был создан композитор
? Мы можем управлять, масштабировать и т.д. контейнер с помощью скрипта || dockerfile?

Хорошо, я беру этот пример, это то, что я использовал для развертывания своей среды тестирования приложений в процессе CI.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

После запуска контейнера я должен подготовить mongodb, управлять очередью и учетной записью в rabbitmq

Сегодня я делаю сценарий с:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

С помощью инструкции onrun я могу напрямую сделать docker-compose -f appmaster.yml -p appmaster up -d
и файл yml стал более читабельным

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Все 131 Комментарий

Я думаю, это должны быть шаги в Dockerfile

FROM mongo:3.0.2
ADD data/mongodb/dumps/latest /data/mongodb/dumps/latest
RUN mongorestore -d database /data/mongodb/dumps/latest/database

Таким образом, вы также сохраните его в кэше при перестройке.

Спасибо @dnephin.
Конечно, я могу создать Dockerfile и использовать его в сборке вместо образов, или я могу использовать docker exec.
MongoDB - это просто пример, вы можете использовать этот пример с mysql и созданием учетной записи или с rabbitmq и созданием очереди и т. Д.

onrun обеспечит гибкость в оркестровке компоновки, compose будет читать текущий список и делать docker exec для каждого элемента.

Дело в том, что помещать команды в docker exec в docker-compose.yml необходимости, если вы можете сделать это либо в Dockerfile, либо в сценарии запуска контейнера, оба из которых также сделают ваш контейнер более полезным, когда _not_ выполняется с помощью Compose.

В качестве альтернативы запустите приложение с помощью сценария оболочки или Makefile, который запускает соответствующие команды docker и docker-compose .

Функциональность не стоит добавлять в Compose, если только она не принесет существенной пользы по сравнению с любым из них, и я не думаю, что это было бы для упомянутых вами вариантов использования.

Итак, чтобы управлять моим докером, вы предлагаете мне использовать скрипт или Makefile. Итак, почему был создан композитор
? Мы можем управлять, масштабировать и т.д. контейнер с помощью скрипта || dockerfile?

Хорошо, я беру этот пример, это то, что я использовал для развертывания своей среды тестирования приложений в процессе CI.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

После запуска контейнера я должен подготовить mongodb, управлять очередью и учетной записью в rabbitmq

Сегодня я делаю сценарий с:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

С помощью инструкции onrun я могу напрямую сделать docker-compose -f appmaster.yml -p appmaster up -d
и файл yml стал более читабельным

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Это было бы довольно полезно и решает вариант использования.

: +1:

Это сделает использование docker-compose более жизнеспособным для закрытых тестов как части конвейера CD.

: +1:

Это дубликат номеров 877, 1341, 468 (и некоторых других).

Я думаю, что правильный способ поддержать это - # 1510 и позволить внешним инструментам выполнять операции, когда вы нажимаете нужное событие.

Закрытие как дубликат

Это было бы очень полезно. Я не понимаю аргумента «о, вы могли бы сделать это с помощью сценария bash». Конечно, мы могли бы сделать это с помощью сценария bash. Я также мог делать все, что делает Docker-compose, с помощью сценария bash. Но дело в том, что существует один единственный файл YAML, который управляет вашей тестовой средой, и его можно развернуть с помощью простой команды docker-compose up .

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

Кроме того, одним важным свойством файла Compose является то, что он довольно легко переносится между машинами - даже машинами Mac, Linux и Windows. Если мы позволим людям помещать произвольные команды оболочки в файл Compose, они станут намного менее переносимыми.

@aanand Честно говоря, возможность выполнить docker exec автоматически не означает несовместимость x-plat.

Извинения - я неправильно интерпретировал эту проблему как связанную с выполнением команд на хост-машине. Тем не менее, моя первая точка зрения остается в силе.

Я понимаю вашу точку зрения @aanand. Мне это не кажется выходящим за рамки возможного, поскольку docker-compose делает то же самое, что и обычный движок docker , например command , expose , ports , build и т. Д. Добавление функциональности exec добавит больше возможностей docker-compose чтобы сделать его настоящим универсальным магазином для настройки вверх по средам разработки.

@aanи основная проблема для многих разработчиков и конвейеров CI - иметь данные, очень близкие к производственной среде. Вроде дамп из БД. Я создаю этот билет 1 год назад, и в docker compose ничего не движется.

Итак, вы предлагаете Makefile или Bashcript просто для запуска некоторого exec https://github.com/docker/compose/issues/1809#issuecomment -128073224

Первоначально я предлагаю onrun (или oncreate), которые сохраняют идемпотентность. Просто беги при первом запуске. Если контейнер остановлен или приостановлен, новый запуск не будет выполняться onrun (или oncreate)

Наконец, в моем репозитории git у меня будет файл компоновки, файл докеров и файл сборки с управлением идемпотентностью (возможно, файл makefile может создать файл состояния). Гений!

Есть большая разница между command , expose и т. Д. И exec . Первая группа - это параметры контейнера, exec - конечная точка command / api. Это отдельная функция, а не опции для функции создания контейнера.

Уже есть несколько способов сделать это с помощью Compose (https://github.com/docker/compose/issues/1809#issuecomment-128059030). onrun уже существует. Это command .

Что касается конкретной проблемы выгрузки или загрузки данных из базы данных, это скорее задачи типа «рабочий процесс» или «автоматизация сборки», которые обычно выполняются в Makefile. Я создавал прототип инструмента для этих случаев, называемого dobi , который выполняет все задачи в контейнерах. Он также очень хорошо интегрируется с Compose. Возможно, вам будет интересно попробовать его, если вас не устраивают Makefiles. Я работаю над примером варианта использования инициализации / загрузки базы данных.

@dnephin onrun - это не просто command потому что вы просто упускаете идемпотентность.

Представим. create при создании контейнера и никогда больше не будет выполняться (дамп и восстановление).

exec:
    create:
        - echo baby
    destroy:
        - echo keny
    start:
        - echo start
    stop:
        - echo bye

Если вам нужно больше примеров:

Спасибо за dobi, но если вам нужно создать инструмент для улучшения компоновки, компоновка - это плохо, и лучше использовать более мощный инструмент.

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

Это все равно, что сказать «если вам нужны приложения для улучшения вашей операционной системы, ваша ОС плохая». Ни один инструмент не должен делать все. Философия unix - делать одно и делать это хорошо . Вот что мы здесь делаем. Compose выполняет одну задачу - «организовывать контейнеры для запуска приложения». Это не инструмент автоматизации сборки.

Это все равно, что сказать «если вам нужны приложения для улучшения вашей операционной системы, ваша ОС плохая». Ни один инструмент не должен делать все. Философия unix - делать одно и делать это хорошо. Вот что мы здесь делаем.

Ух ты, я думаю, что мы достигли лучшего недобросовестности.

К сожалению, простой многократно используемый компонент - это не то, как обстоят дела. В настоящее время Docker создает инструменты для запуска облачных серверов, систем для кластеризации и широкого спектра функций: создание образов, запуск образов, выгрузка, загрузка и, в конечном итоге, даже наложение сетей, все скомпилировано в один монолитный двоичный файл, работающий в основном как root на вашем сервере. . Стандартный контейнерный манифест был удален. Мы должны перестать говорить о контейнерах Docker и начать говорить о платформе Docker. Он не становится простым компонуемым строительным блоком, о котором мы мечтали.

Значит, вы можете гарантировать, что мы никогда не увидим, что "docker compose" написано на Go inside в монолитном двоичном файле docker, чтобы сохранить философию unix? https://www.orchardup.com/blog/orchard-is-joining-docker

Чтобы продолжить достижение этой первоначальной цели, мы присоединяемся к Docker. Среди прочего, мы продолжим работать над тем, чтобы сделать Docker лучшим опытом разработки, который вы когда-либо видели - как с Fig, так и путем включения лучших частей Fig в сам Docker.

Короче говоря, нет возможности делать такие вещи, как загрузка фикстур с помощью compose ..? Должен сказать, я удивлен ..
Официальный способ - добавить загрузку приспособлений в мой производственный контейнер? Или написать сценарий оболочки вокруг моего файла композиции? В последнем случае я мог бы просто выполнить docker run, как делал раньше.

@discordianfish , если кто-то каким-то образом

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

Довольно утомительно заставлять мои внешние скрипты знать, будет ли up создавать или запускать контейнеры ...

И с этим могут помочь некоторые хуки жизненного цикла + команды + переменные среды.

Вы видите это в фреймворках управления услугами и других инструментах оркестровки ... почему бы не в docker-compose?

Возможно, вас заинтересует https://github.com/dnephin/dobi - инструмент, над которым я работал и который был разработан для этих рабочих процессов.

@dnephin, прекратите

Спасибо за конструктивный комментарий. Я не понимал, что уже упоминал Доби в этой теме 8 месяцев назад.

Если вам нравится Makefile / bash, это прекрасно! Я рад, что твоя проблема решена.

Добавлен комментарий по этой теме здесь: https://github.com/docker/compose/issues/1341#issuecomment -295300246

@dnephin для этого, мой комментарий может быть применен:

Так грустно, что этот выпуск закрыт из-за некоторой невосприимчивости к эволюции: разочарован:

Самая большая ценность docker compose - это стандартизация

В этом-то и дело. Если бы мы могли «просто» написать файл .sh или что-то еще для выполнения работы без использования Docker Compose, почему существует Docker Compose? :смущенный:

Мы понимаем, что это большая работа, как сказал @ shin-:

к сожалению, это слишком большая нагрузка для поддержки на этом этапе проекта

:сердце:

Но вы не можете сказать «Сделайте сценарий», что означает «Эй, это слишком сложно, мы не справимся».

Если это сложно сделать, просто скажите: «Ваша идея интересна, и она удовлетворяет некоторые потребности, но это действительно сложно реализовать, и у нас нет ресурсов для этого в настоящее время ... запрос на перенос "или что-то в этом роде: bulb:

В # 1341 я "только" вижу способ записать в docker-compose.yml команды, такие как nmp install , которые будут выполняться до или после некоторых событий (например, создания контейнера), как если бы вы сделали с docker exec <container id> npm install Например,

Пример использования

У меня есть собственный образ NodeJS, и я хочу запустить npm install в созданном из него контейнере с docker-compose up --build .

Моя проблема: код приложения не добавляется в контейнер, он монтируется в нем с объемом, определенным в docker-compose.yml :

custom-node:
    build: ../my_app-node/
    tty: true
    #command: bash -c "npm install && node"
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app

поэтому я не могу запустить npm install в Dockerfile, потому что ему нужен код приложения для проверки зависимостей. Я описал поведение здесь: http://stackoverflow.com/questions/43498098/what-is-the-order-of-events-in-docker-compose

Чтобы запустить npm install , мне нужно использовать обходной путь, инструкцию command :

command: bash -c "npm install && node"

который не совсем чистый: разочарованный: и который я не могу запустить в версиях Alpine (в нем не установлен Bash).

Я думал, что Docker Compose предоставит способ запускать команды exec в контейнерах, например:

custom-node:
    build: ../my_app-node/
    tty: true
    command: node
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app
    exec:
     - npm install

Но это не так, и я думаю, что его действительно не хватает!

Я ожидал, что compose предназначен для тестирования, но я, вероятно, ошибаюсь, и он предназначен больше для локальной разработки и т. Д. Я столкнулся с несколькими другими грубыми краями, такими как потерянные контейнеры и нечеткая связь между именем проекта, путем и тем, как он используется для идентификации собственности, что произойдет, если у вас есть несколько файлов компоновки в одном каталоге и т. д. Так что в целом это не кажется подходящим для CI.
Вместо этого я планирую повторно использовать свои производственные манифесты k8s в CI, запустив автономный kubelet. Для этого также потребуется много клея, но, по крайней мере, так я могу использовать одни и те же объявления для dev, test и prod.

@ lucile-sticky вы можете использовать sh -c в alpine.

Похоже, что вам нужна «автоматизация сборки», которая не является ролью docker-compose. Вы смотрели на Доби ?

Два вопроса:

  • Почему это не роль Docker Compose?
  • Если цель состоит в том, чтобы иметь только один инструмент для управления ими всеми, зачем мне использовать другой инструмент для выполнения задачи, которую Docker Compose не может выполнить?

Эта функция очень нужна!

@ lucile-липкий

Почему это не роль Docker Compose?

Потому что роль Compose четко определена и не включает эти функции.

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

Если цель состоит в том, чтобы иметь только один инструмент для управления ими всеми, зачем мне использовать другой инструмент для выполнения задачи, которую Docker Compose не может выполнить?

Мы не хотим быть единственным инструментом, чтобы управлять ими всеми. Мы следуем философии UNIX и верим в то, что «каждая программа должна хорошо выполнять одну задачу. Чтобы выполнить новую работу, создавайте заново, а не усложняйте старые программы, добавляя новые функции».
Можно не согласиться с этой философией, но именно так мы в Docker разрабатываем программное обеспечение.

Я создаю эту проблему в августе 2015 года, каждый год кто-то добавляет комментарий, и мы повторяем одни и те же вопросы с одинаковыми ответами (и вы наверняка увидите, как @dnephin публикует рекламу своего инструмента).

@ shin-

В инструментах оркестрации нельзя разделить «сборку» и «подготовку».

Например, вы знаете одного из них:

Когда вы настраиваете службу, вы должны ее предоставить. Если я развертываю tomcat, я должен подготовить его к войне, если я создаю БД, мне нужно вводить данные и т. Д. Независимо от того, как должен запускаться контейнер (пусть это управляет разработчик образа). Основная цель «Provider» в случае Compose - избежать недоразумений между тем, «что запускает мой контейнер» и «что это за предоставление».

Как сказано в вашей цитате в документе "Compose", вы используете файл Compose для настройки служб вашего приложения. Затем , используя одну команду, вы создаете и запускаете все службы из своей конфигурации "

Философия Unix? Дай мне посмеяться. Я указываю вам на тот же ответ, что и в этом выпуске https://github.com/docker/compose/issues/1809#issuecomment -237195021.
Посмотрим, как «moby» будет развиваться в философии Unix.

@ shin- docker-compose ни в коем случае не придерживается философии Unix. Если бы docker-compose придерживался философии Unix, были бы отдельные команды для каждой из build, up, rm, start, stop и т. Д., И каждая из них имела бы пригодные для использования stdin, stdout и stderr, которые работали бы согласованно. говорит системный администратор unix с более чем 20-летним опытом работы, включая System V, HP-UX, AIX, Solaris и Linux

Вернемся к обзору Compose

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

В конечном итоге docker-compose - это инструмент оркестровки для управления группой служб на основе контейнеров, созданных из образов докеров. Его основные функции - «создавать», «запускать», «останавливать», «масштабировать» и «удалять» сервисы, определенные в файле docker-compose.yml.

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

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

Я думаю, что это входит в компетенцию docker-compose, учитывая, что это инструмент оркестровки и он знает об изменениях состояния. Я не считаю, что события или внешние сценарии подходят для этого варианта использования. Они не идемпотентны, гораздо сложнее запустить «вторую» службу рядом с композицией, чтобы следить за событиями. Независимо от того, работают ли хуки внутри контейнера или вне контейнера, является деталью реализации.

В конце концов, пользователи docker-compose выражают реальную потребность, и @dnephin , @ shin-, похоже, ее отклоняют. Было бы хорошо, если бы это было включено в дорожную карту.

Этот тип функциональности в настоящее время блокирует мое внедрение Docker в мои тестовые и производственные развертывания. Я действительно хотел бы, чтобы этот вопрос был решен как-нибудь, а не отклонен.

Думаю, это будет очень полезно!

Для меня проблема в том, что когда есть контейнер приложения A, работающая служба 'a', зависящая от db контейнера B, работающая служба b. Затем контейнер выходит из строя, если его b не настроен.
Я бы предпочел использовать образы концентратора докеров вместо того, чтобы переписывать свои собственные файлы Docker. Но это означает, что A не работает и контейнер не создается. Единственный вариант в противном случае -

  1. Используйте B как базовый образ и создайте свой собственный Dockerfile.
  2. Пусть A завершится ошибкой, настройте b в сценарии и перезапустите A.

У меня точно такой же вариант использования, как у @ lucile-sticky.

@lekhnath для моего случая, я решил это, отредактировав параметр command в моем docker-compose.yml :

command: bash -c "npm install && node"

Но это так уродливо ТТ

@ lucile-sticky Следует отметить, что это отменяет любую команду, установленную в Dockerfile контейнера. Я работал над этим, монтируя собственный сценарий оболочки с помощью volumes , заставляя command в моем файле Docker Compose запускать этот сценарий и включая в него исходный CMD из Dockerfile .

Почему этот вопрос закрыт? _напишите сценарий bash_ или _используйте этот инструмент, который я написал_ не является веской причиной для закрытия этой проблемы.

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

@dnephin Считаете ли вы, что запуск сценариев инициализации выходит за рамки развертывания приложений на основе контейнеров? в конце концов, compose - это «определение и запуск многоконтейнерных приложений с помощью Docker».

Кто-нибудь посмотрел на Доби, если у вас нет, пожалуйста, сделайте это здесь :)
image

Думаю, с этим ничего не случилось. Мне бы хотелось увидеть какую-то функциональность в файле docker-compose где мы могли бы записывать, когда команда должна быть выполнена, например, в примере @ ahmet2mir .

Очень грустно видеть, что эта функция не реализована.

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

Невероятно, что эта функция еще не реализована!

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

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

О, тогда давайте сделаем это unix-way .
_Just_ (затем мультиплексирование) конвейер docker-compose up stdin к каждому контейнеру CMD ?
Чтоб такой yaml файл

services:
  node:
    command: sh -

выполнит эту работу: cat provision.sh | docker-compose up
контейнеры для EXEC uting вещей, я не вижу , лучше использовать стандартный ввод , чем прохождение команд вперед.

Альтернативой может быть:

services:
  node:
    localscript: provision.sh

Хотя немного ориентирован на оболочку, что решит 99% сценариев использования.

Несмотря на то, что есть допустимые варианты использования и множество положительных отзывов по этому поводу ... очевидно, что это все еще отклонено. Позор, поскольку я, как и многие другие здесь, нашел бы это чрезвычайно полезным.

Добавление моего +1 к большому стеку существующих +

... еще +1 здесь!

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

+1 +1

Пока я жду эту функцию, я использую следующий сценарий для выполнения аналогичной задачи:

docker-start.sh

#!/usr/bin/env bash

set -e
set -x

docker-compose up -d
sleep 5

# #Fix1: Fix "iptable service restart" error

echo 'Fix "iptable service restart" error'
echo 'https://github.com/moby/moby/issues/16137#issuecomment-160505686'

for container_id in $(docker ps --filter='ancestor=reduardo7/my-image' -q)
  do
    docker exec $container_id sh -c 'iptables-save > /etc/sysconfig/iptables'
  done

# End #Fix1

echo Done

@ reduardo7 Тогда вы могли бы вообще отказаться от docker-compose, чтобы иметь на одну зависимость меньше.

@omeid , ты прав! Это обходной путь для выполнения аналогичной задачи, извините!

@ reduardo7 Не нужно извиняться, то, что вы опубликовали, вероятно, будет полезно некоторым людям.
Я просто указывал, что исходный выпуск все еще стоит и не должен был быть закрыт. :)

Я понимаю, что такое @dnephin , упомянутые здесь функции могут быть заменены достаточно разными функциями.

Однако, если такие шаблоны используются часто, как насчет того, чтобы представить руководство (или какой-нибудь тест), чтобы другие могли легко его использовать?

Кажется, нет никаких сомнений в том, что этот шаблон можно использовать часто.

@MaybeS Единственное разногласие в том, что @dnephin скорее видит, как продвигается его дурацкий инструмент, вместо того, чтобы помогать делать docker-compose лучше.

@omeid да, действительно.

сегодняшний пример желания создать способ выполнения некоторой формы onrun

version: "3.3"
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        # NOTE: this URL needs to be right both for users, and for the runner to be able to resolve :() - as its the repo URL that is used for the ci-job, and the pull url for users.
        external_url 'http://gitlab:9090'
        gitlab_rails['gitlab_shell_ssh_port'] = 2224
    ports:
      - '9090:9090'
      - '2224:22'
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock

и, конечно же, бегун не зарегистрирован - и для этого нам нужно

  1. вытащить токен из базы данных в gitlab
  2. запустить регистр в контейнере бегуна

поэтому вместо того, чтобы определять развертывание моего многоконтейнерного приложения только в docker-compose, мне нужно использовать некоторые дополнительные средства - в данном случае ... документы?

export GL_TOKEN=$(docker-compose exec -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
docker-compose exec gitlab-runner gitlab-runner register -n \
  --url http://gitlab:9090/ \
  --registration-token ${GL_TOKEN} \
  --executor docker \
  --description "Docker Runner" \
  --docker-image "docker:latest" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock \
  --docker-network-mode  "network-based-on-dirname-ew_default"

ммм, я мог бы что-то взломать, благодаря чему у меня есть другой контейнер с сокетом докера и docker exec's

что поспорить, есть способ ....

например, я могу добавить:

  gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: bash
    command: -c "sleep 200 && export GL_TOKEN=$(docker-compose -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c \"SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1\"') && docker-compose exec gitlab-runner gitlab-runner register -n --url http://gitlab:9090/ --registration-token ${GL_TOKEN} --executor docker --description \"Docker Runner\" --docker-image \"docker:latest\" --docker-volumes /var/run/docker.sock:/var/run/docker.sock --docker-network-mode  \"simaaustraldeployment_default\""

в мой файл набора - хотя мне нужен какой-то цикл / ожидание, так как gitlab не готов сразу - sleep 200 может быть недостаточно.

Итак - вы __can__ взломаете какой-то шаблон, подобный этому, прямо в docker-compose.yml - но лично я бы предпочел более чистую поддержку, чем эта :)

@SvenDowideit onrun уже существует, это entrypoint или cmd .

Сценарий точки входа для этого изображения даже предоставляет вам ловушку. $GITLAB_POST_RECONFIGURE_SCRIPT может быть установлен как путь к сценарию, который он будет запускать после завершения всех настроек (см. /assets/wrapper на изображении). Задайте в переменной env путь к вашему скрипту, который выполняет регистрацию psql +, и все готово.

Даже если в изображении не было этого крючка, его можно довольно легко добавить, расширив изображение.

хотя мне нужен какой-то цикл / ожидание, так как gitlab не готов сразу - сна 200 может быть недостаточно.

Это было бы необходимо даже с опцией «exec-after-start». Поскольку сценарий точки входа на самом деле обеспечивает ловушку, я думаю, что в этом решении, вероятно, нет необходимости.

нет, я (думаю) вы пропустили часть проблемы, которую я показываю:

в моем случае мне нужен доступ к обоим контейнерам, а не только к одному, поэтому точка входа / команда _не_ дает мне это.

GL_TOKEN поступает из контейнера gitlab и затем используется в контейнере gitlab-runner для регистрации.

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

Я работал над тем, чтобы сделать их немного более волшебными - что в основном означает, что в моем контейнере инициализации есть несколько циклов сна, так как gitlab сам инициализирует некоторое время.

TBH, я начинаю чувствовать, что использование сценария, запущенного в контейнере инициализации, который использует сам файл compose и образ docker / compose, _ является_ правильным способом скрыть такую ​​сложность - для непроизводственных "попробуйте меня, и это просто сработает в подобных ситуациях.

_ Если_ мне нужно было подумать о каком-то странном синтаксическом сахаре, чтобы помочь, возможно, я бы пошел на что-то вроде:

gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: ['/bin/sh']
    command: ['/init-gitlab.sh']
    file:
      path: /init-gitlab.sh
      content: |
            for i in $(seq 1 10); do
                export GL_TOKEN=$(docker-compose -f gitlab-compose.yml -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
                echo "$i: token($?) == $GL_TOKEN"
                ERR=$?

                if [[ "${#GL_TOKEN}" == "20" ]]; then
                    break
                fi
                sleep 10
            done
            echo "GOT IT: token($ERR) == $GL_TOKEN"

            for i in $(seq 1 10); do
                if  docker-compose -f gitlab-compose.yml  -p sima-austral-deployment exec -T gitlab-runner \
                    gitlab-runner register -n \
                    --url http://gitlab:9090/ \
                    --registration-token ${GL_TOKEN} \
                    --executor docker \
                    --description "Docker Runner" \
                    --docker-image "docker:latest" \
                    --docker-volumes '/var/run/docker.sock:/var/run/docker.sock' \
                    --docker-network-mode  "simaaustraldeployment_default" ; then
                        echo "YAY"
                        break
                fi
                sleep 10
            done

то есть, например, cloud-init: http://cloudinit.readthedocs.io/en/latest/topics/examples.html#writing -out-random-files

но когда дело доходит до этого - у нас есть решение для координации сложных многоконтейнерных вещей изнутри docker-compose-yml.

Если вы можете установить предопределенный токен, вы можете сделать это из сценария точки входа в gitlab-runner . Разве нет возможности установить эту опору времени?

@dnephin В тот момент, когда вы упоминаете сценарий, вы ошибаетесь на световой год, а затем и на несколько.

onrun - это не то же самое, что entrypoint или cmd .

entrypoint / cmd предназначен для настройки исполняемого файла, который будет работать как контейнеры init / PID 1.

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

@dnephin , вероятно, было бы более полезно, если бы вы сосредоточились на общем наборе проблем, а не пытались обойти проблемы конкретного набора контейнеров.

Однако из того, что я видел, нет, это сгенерированный секрет - но на самом деле это не единственное требование координирования работы с несколькими контейнерами даже в этой небольшой игровой системе - это просто самый быстрый способ для меня прототип публично.

Как это возможно, что мы смогли переопределить entrypoint и command в файле создания, начиная с версии 1 (https://docs.docker.com/compose/compose-file/compose-file -v1 / # entrypoint) и по-прежнему нет такой директивы, как onrun для запуска команды, когда контейнеры подняты?

TBH, я действительно не думаю, что onrun правдоподобно - Docker или оркестратор не знает, что означает "все контейнеры" - в одном из моих случаев HEALTHCHECK завершится ошибкой, пока я не сделаю некоторые дополнительные "вещи", когда я получаю информацию из одного контейнера и использую ее, чтобы избавиться от некоторых других вещей в других контейнерах.

И _ если_ я правильно понял, это означает, что мне в основном нужен контейнер Operator, который содержит код, который определяет, когда некоторые части многоконтейнерной системы достаточно готовы для выполнения некоторой работы (промыть и повторить), пока он либо завершил свою работу и уходит, либо, возможно, даже следит за событиями и исправляет их.

И мне кажется, что эта задача лучше всего решается (в docker-compose) с помощью контейнера docker-compose с кодом.

Я, вероятно, собираюсь поиграть с тем, как затем преобразовать этот оператор во что-то, что может работать со стеками роя докеров (из-за других потребностей проекта).

Я не совсем уверен, что есть много синтаксического сахара, которое можно было бы добавить в docker-compose, если только это не что-то вроде маркировки контейнера как «это оператор, дайте ему магические способности».

Хорошо видно, что разработчики не хотят слушать пользователей .. Я посмотрю на какой-нибудь другой инструмент ... docker-compose - большая боль .. Я не понимаю, почему вы не можете понять, что единственная полезная вещь, которая приходит from docker-composer - это инструмент сборки ... Я потратил много времени на поиск, КАК я могу запустить команду SIMPLE, чтобы добавить разрешения внутри контейнера для активного пользователя ..

Похоже, что docker-composer просто НЕ СДЕЛАНО ...

Я тоже хочу что-то, что будет onrun в моем файле создания

__BUT__, ни контейнеры, ни compose не имеют возможности узнать, что означает onrun . Вот почему существует шаблон оператора и почему я сделал примеры в https://github.com/docker/compose/issues/1809#issuecomment -362126930

__is__ возможно сделать это сегодня - по сути, вы добавляете службу onrun которая ждет, пока все другие службы действительно не будут готовы к взаимодействию (в случае gitlab, это занимает довольно много времени), а затем все, что вам нужно сделать, чтобы координировать дела.

Если что-то не работает с этим, сообщите нам, и мы посмотрим, сможем ли мы что-нибудь выяснить!

Я тоже хочу что-то, что будет работать в моем файле создания

НО ни у контейнеров, ни у compose нет способа узнать, что означает onrun.

Насколько я понимаю, onrun за службу означает, что запускается первый процесс контейнера. В большем количестве случаев контейнер в любом случае выполняет только один процесс, так как это рекомендуемый способ запуска контейнеров.

Проблема кроссплатформенной поддержки была решена ранее, поскольку команда может быть полностью независимой от ОС через docker exec , точно так же, как RUN не обязательно означает команду linux в Dockerfile.
https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/manage-windows-dockerfile

Все еще жду возможности onrun

Мне тоже нужны эти onrun функции, я думал, что они есть в этом инструменте. Из-за отсутствия этой функции теперь мне нужно поддерживать 2 скрипта man.

Ребята, а если бы я сделал обертку вокруг этой docker-compose и разрешил эту onrun фичу? Вы бы использовали это, ребята?

@wongjiahau может быть что-то вроде этого? https://github.com/docker/compose/issues/1809#issuecomment -348497289

@ reduardo7 Да, я подумал о том, чтобы обернуть его внутрь скрипта с именем docker-composei и с docker-composei.yml который содержит атрибут onrun .
Кстати, docker-composei означает docker-compose improved .

Реальное решение, вероятно, состоит в том, чтобы создать образ «Orchestrator», который запускает и управляет (через сценарии bash) «изображениями приложений» (возможно, с использованием докера) изнутри. В противном случае мы всегда будем просить о дополнительных функциях для инструмента, который «не предназначен для того, чтобы делать то, что мы хотим».

Так что мы должны даже рассмотреть Docker в Docker ...

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

Учитывая преобладающую тенденцию к тому, чтобы контейнеры были автономными, с одной службой на контейнер, контейнер должен быть самодостаточным с точки зрения осведомленности о своем рабочем контексте. То, что вытекает из этого файла, должно быть средой для определения этого, а не прикрепленными скриптами. С этим трудно спорить, если только вы не являетесь эгоцентричным фанатиком.

В моем случае мои контейнеры redis загружают сценарии lua после запуска сервера redis. В обычной неконтейнерной среде я получаю systemd для запуска сценария после запуска. Простой и совместимый с архитектурой systemd. Аналогичный принцип должен существовать для compose, учитывая его роль в настройке контекста для запуска контейнеров.

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

поэтому решение (после прочтения всего этого потока) заключается в использовании сценария bash для выполнения работы ... в этом случае я удалю docker-compose (мы можем делать все с помощью команды docker cmd ...)

спасибо, разработчик, чтобы выслушать людей, которые используют ваши вещи :)

Увидев количество сообщений, содержащих аргументы и контраргументы, противостоящие простым предложениям (например, наличие события

Пожалуйста, давайте сделаем Open Source по-настоящему открытым.

какие-нибудь обновления по этой функции? в чем проблема?

@ v0lume Полагаю, вы даже не удосужились прочитать ответы в этой статье

Похоже, что решения все еще нет ... Я хотел бы поделиться хакерским обходным путем.
Указав версию «2.1» в docker-compose.yml, вы можете злоупотребить тестом проверки работоспособности, чтобы запустить дополнительный код внутри образа при его запуске. Вот пример:

version: '2.1'
services:
    elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3
        healthcheck:
            test: |
                curl -X PUT elasticsearch:9200/scheduled_actions -H "ContentType: application/json" -d '{"settings":{"index":{"number_of_shards":'1',"number_of_replicas":'0'}}}' &&
                curl --silent --fail localhost:9200/_cat/health ||
                exit 1
            interval: 11s 
            timeout: 10s 
            retries: 3
        environment:
            - discovery.type=single-node
            - ES_JAVA_OPTS=-Xms1g -Xmx1g
            - xpack.security.enabled=false
    main:
        image: alpine
        depends_on:
            elasticsearch:
                condition: service_healthy

Если сценарий проверки работоспособности, который вы пишете, завершается с кодом> = 1, он может выполняться несколько раз.
Проверка работоспособности службы будет выполняться только в том случае, если от нее зависит другая служба и задает условие service_healthy как показано в примере.

Мне нравится подход @T-vK, и я уже успешно его использовал. Но хочу поделиться еще одним ... хаком:

# Run Docker container here

until echo | nc --send-only 127.0.0.1 <PORT_EXPOSED_BY_DOCKER>; do
  echo "Waiting for <YOUR_DOCKER> to start..."
  sleep 1
done

# Do your docker exec stuff here

+1
Я полностью согласен с этим, потому что эта функция необходима, и она уже реализована другими оркестраторами докеров, такими как kubernetes. Он уже имеет крючки жизненного цикла для контейнеров и задокументирован здесь .

Но позвольте мне предложить вариант использования, который вы не можете решить с помощью Dockerfiles.

Допустим, вам нужно смонтировать том во время выполнения и создать символическую ссылку из вашего контейнера на том, не зная заранее точное имя каталога. У меня был случай, когда имя каталога было динамическим, в зависимости от среды, в которой я развертывал, и я передавал его как переменную.

Конечно, я нашел обходной путь для решения этой проблемы, а их несколько. С другой стороны, хуки дадут мне гибкость и лучший подход к динамическому внесению изменений без необходимости взламывать что-либо и заменять Dockerfile.

Я рад, что нашел эту проблему. Я играл с Docker и Docker compose пару лет. Теперь серьезно надеялся использовать его как инструмент для начала масштабирования системы. Я буду проверять это раз в год или два, но, исходя из отношения сопровождающих проекта, я просто буду использовать либо скрипты, либо какой-либо другой инструмент. Рад, что не потратил много времени и обнаружил это на ранней стадии.

Совет от профессионала: если кто-то, кто только начинает переводить свой рабочий процесс на этот тип инструмента, уже нуждается в том, что описано здесь, возможно, стоит переосмыслить, «зачем» вы это создаете. Да, вы успешны, но это потому, что люди использовали эту вещь в первую очередь, и вы, вероятно, были очень открыты, чтобы дать им то, что им нужно.

Всего наилучшего.

Я могу дать вам все, что вы хотите (кроме моей девушки), если эта функция будет реализована, и я буду самым счастливым человеком во всей вселенной :)

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

Было бы неплохо.

Чтобы добавить к этому, учитывая следующее:

services:
    web:
        image: node:8-alpine
        depends_on:
            - db
    db:
        image: postgres:alpine
        onrun: "echo hi"

было бы слишком много добавлять сценарии между событиями?

    web:
        events:
            db_onrun: "connectAndMigrate.sh"

На мой взгляд, добавить это в docker-compose несложно, и это касается не только вас, использующих compose file и compose stack, но и других разработчиков в вашей команде.

  • Использование отдельных контейнеров - каждый должен знать, что они должны их запускать.
  • Напишите собственный Dockerfile - у нас около 20 сервисов, и для каждой службы я должен переопределить Dockerfile, чтобы запустить какую-нибудь команду.

Нам нужно установить и настроить mkcert , например, в каждой среде, чтобы иметь доверенные сертификаты. Он не является частью контейнера или Dockerfile, так как не требуется на этапе / производстве. Каков правильный подход к установке инструмента, и все, кто использует файл compose, даже понятия не имеют, что происходит за кулисами?

Добавление еще одного варианта использования:

Нужен был экземпляр wordpress. Написал свой docker-compose.yaml. docker-compose up - Упс! Необходимо установить разрешения для файлов в каталоге плагинов ... Не могу найти другого способа заставить его работать, нужно установить разрешения после запуска контейнера, потому что я привязываю некоторые файлы с хоста, и это кажется единственным способом чтобы исправить разрешения fs, выполните chown -Rf www-data.www-data /var/www/wp-content изнутри контейнера. Напишите свой собственный Dockerfile и соберите его только для этого? Мне это кажется глупым.

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

Рад видеть, что эти привратники, @dnephin , @aanand , @ shin-, получают за это много тепла. Это действительно говорит о многом, когда все сообщество кричит как можно громче, а основные разработчики просто сидят сложа руки и отказываются слушать. Это тоже типично. Давайте посчитаем не только количество поднявших палец вверх, но и 34 пользователя, которые ответили, что это необходимо:
01) sshishov (сшишов)
02) fescobar (фескобар)
03) sandor11 (сандор11)
04) web-ted (веб-тед)
05) v0lume
06) webpolis
07) Skull0ne
08) usergoodvery (пользовательское добро)
09) wongjiahau (wongjiahau)
10) MFQ
11) yosefrow (йосфроу)
12) bagermen (багермены)
13) daqSam
14) omeid (омейд)
15) dantebarba (дантебарба)
16) willyyang (виллиянг)
17) SharpEdgeMarshall
18) lost-carrier (потерянный перевозчик)
19) ghost (призрак)
20) rodrigorodriguescosta (родригородригэскоста)
21) datatypevoid (тип данных)
22) dextermb (декстермб)
23) lekhnath (лекнатх)
24) lucile-липкий
25) rav84 (рав84)
26) dopry (допры)
27) ahmet2mir (ахмет2мир)
28) montera82
29) discordianfish (дискордианфиш)
30) jasonrhaas (ясонраас)
31) fferraris (фферрарис)
32) hypergig (гипергиг)
33) sunsided (солнечные лучи)
34) sthulb (Стхульб)

А номер, который сказал нет? Колоссальные 3:
01) dnephin (днефин)
02) aanand (ананд)
03) shin-

Хммм ... от 34 до 3 ...

@ rm-rf-etc хорошая аналитика ... Я даже не думаю, что @dnephin или @aanand больше работают над docker-compose. Если повезет, Docker планирует отказаться от компоновки в пользу стеков, и здесь не останется команды, на которую можно было бы жаловаться, и мы снова начнем наблюдать за прогрессом в работе над продуктом.

Добавление еще одного варианта использования:

Нужен был экземпляр wordpress. Написал свой docker-compose.yaml. docker-compose up - Упс! Необходимо установить разрешения для файлов в каталоге плагинов ... Не могу найти другого способа заставить его работать, нужно установить разрешения после запуска контейнера, потому что я привязываю некоторые файлы с хоста, и это кажется единственным способом чтобы исправить разрешения fs, выполните chown -Rf www-data.www-data /var/www/wp-content изнутри контейнера.

В этом случае вы также можете установить свойство user в своем файле Compose

Напишите свой собственный Dockerfile и соберите его только для этого? Мне это кажется глупым.

Похоже, у вас сложилось твердое мнение; но на самом деле не было бы ничего «глупого» в написании файла Docker для изменения базового образа в соответствии с вашими потребностями. Это первоначальная цель всех базовых изображений.

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

Рад видеть, что эти привратники, @dnephin , @aanand , @ shin-, получают за это много тепла.

Да, хорошее отношение, приятель. : D


@ rm-rf-etc хорошая аналитика ... Я даже не думаю, что @dnephin или @aanand больше работают над docker-compose.

Да, прошло несколько лет - не нужно постоянно пинговать их по старым вопросам.

Если повезет, Docker планирует отказаться от компоновки в пользу стеков, и здесь не останется команды, на которую можно было бы жаловаться, и мы снова начнем наблюдать за прогрессом в работе над продуктом.

🙄

@ shin- но ты только что ответил на него

Недавно я снова столкнулся с этой проблемой, и хотя это можно сделать, как показано в моем обходном пути , это работает, только если вы укажете 2.1, что воняет имо.

Меня просто ошеломляет, что официальная позиция, кажется, заключается в том, что вы должны создавать свои собственные образы докеров для всего.
Для меня это буквально то же самое, что сказать: «Если вы хотите изменить настройку в любой программе, вы должны изменить исходный код и перекомпилировать его».
Каждый раз, когда вы добавляете новую службу или хотите перейти на новую версию… например, образ MongoDB или MySQL Docker, вам придется создавать новый файл Dockerfile, создавать его и, возможно, помещать в реестр.
Это огромная трата времени и ресурсов по сравнению с тем, как это было бы, если бы вы могли просто изменить image: mongo:3.0.2 на image: mongo:3.0.3 в своем docker-compose.yml.
Я не разглагольствую о долгом времени сборки, я рассуждаю о том, что вам нужно возиться с Dockerfiles и docker build когда все, что вам нужно, это обновить или изменить параметр службы, которая потенциально даже не предназначен для использования в качестве базового изображения.

И аргумент, что каждое приложение должно делать что-то одно и только одно, тоже воняет. Речь идет даже не о реализации совершенно новой функции, а о передаче другого параметра в docker . Также возникает вопрос, почему docker run , docker build , docker exec , docker pull и т. Д. Являются частью одного приложения. Аргумент сейчас звучит лицемерно, не так ли?

@ shin-, я перешел по вашей ссылке и не понимаю, какое значение имеет свойство пользователя для установки владельца каталога, подключенного к привязке. Кажется, связано с портами.

Re: Relationship: Похоже, люди со мной согласны, так что воспринимайте это как сильную обратную связь. Извините, если вам не нравится, как я это выражаю, но на самом деле кажется, что требования пользователя игнорируются, так чего еще вы ждете?

Я приехал сюда в надежде на такую ​​функциональность, как onrun: предлагается, поскольку я использую compose всего через два дня, и для меня такой инструмент должен иметь эту функциональность.

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

Черт, я прочитал всю переписку, чтобы найти ответ: «Хорошо, ребята, мы наконец поняли, что это круто, и мы это реализуем». Печально видеть, что этого не произошло.
+1 к бегу!

@fabiomolinar , Есть одно решение, которое мы широко используем в наших производственных роях, но оно не так хорошо, как мероприятие.

Мы используем следующий якорь

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

повторять задачи, пока они не станут успешными. Мы создаем контейнеры для задач миграции и настройки, которые имеют идемпотентные результаты, и запускаем их таким образом в нашей локальной композиции и в наших стеках.

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

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

@fabiomolinar , вот пример того, как мы используем этот подход в наших сервисах создания ...

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

#### configure a service to always restart
x-service: &service
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: any
  # for compose (not supported by stack)
  restart: always

services: 
  accounts: &accounts
    <<: *service
    image: internal/django
    ports:
      - "9000"
    networks:
      - service
    environment:
      DATABASE_URL: "postgres://postgres-master:5432/accounts"
      REDIS_URL: "hiredis://redis:6379/"

  accounts-migrate:
    <<: *accounts
    <<: *task
    command: ./manage.py migrate --noinput

Спасибо, что указали на это @dopry. Но мой случай был несколько проще. Мне нужно было запустить мой сервер, а затем, только после того, как он заработал, мне нужно было выполнить некоторые задачи по развертыванию. Сегодня я нашел способ сделать это, выполнив небольшое управление процессами в одной строке CMD . Представьте, что процессы сервера и развертывания называются server и deploy соответственно. Затем я использовал:

CMD set -m; server $ deploy && fg server

Вышеупомянутая строка устанавливает режим монитора bashes, затем запускает процесс server в фоновом режиме, затем запускает процесс deploy и, наконец, переносит процесс server в снова на переднем плане, чтобы Docker убивал контейнер.

Пока мы обсуждаем это, у кого-нибудь есть подсказка о том, как запустить команду в контейнере или хосте после запуска docker-compose up ?

Я понимаю, что выполнение любой команды на хосте может поставить под угрозу уровни безопасности, но я просто хотел бы rm каталог до или во время запуска контейнера. Каталог доступен как на хосте, так и на контейнере. Я не хочу создавать собственный образ Docker или иметь сценарий, который сначала rm а затем запускает docker-compose .

Благодаря!

@fabiomolinar , Ваш подход нарушает несколько принципов приложения с 12 факторами . Если вы контейнеризуете свою инфраструктуру, я настоятельно рекомендую строго придерживаться их.

Некоторые проблемы, которые могут возникнуть из-за вашего подхода

  1. медленный запуск контейнера.
  2. при масштабировании службы с помощью контейнера развертывание будет выполняться один раз для каждого экземпляра, что может привести к некоторым интересным проблемам параллелизма.
  3. сложнее отсортировать логи от «задачи» и службы для управления и отладки.

Поначалу я нашел подход, который рекомендую, противоречащим интуиции. Он хорошо зарекомендовал себя на практике в наших локальных средах разработки в кластерах docker-compose, docker swarms и mesos / marathon. Это также эффективно работало с отсутствием «непрерывности».

Подход, который я использовал, действительно очень уродлив. Я использовал его какое-то время, просто чтобы запустить свою среду разработки. Но я уже изменил это, чтобы использовать сценарии точки входа и команду at для запуска сценариев после того, как сервер запущен и работает. Теперь мой контейнер работает с правильным процессом как PID 1 и правильно реагирует на все сигналы.

Нам это еще нужно. Я не могу найти способ выполнить свертки базы данных после успешного запуска контейнера, не добавляя его в кучу Makefile.

@ victor-perov создать еще один контейнер для задачи сворачивания и выполнить его как отдельную службу

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

x-task: &task
  # run once deploy policy for tasks
  deploy:
    restart_policy: 
      condition: none
    replicas: 1

service:
  automata-auth-migrate:
    <<: *automata-auth
    <<: *task
    # without the sleep it can't lookup the host postgres.  maybe the command is ran before the network set is complete.
    command: sleep 5 && python /code/manage.py migrate --noinput

Что ж, это четвертый год, до которого растянулось обсуждение. Итак, позвольте мне добавить мой +1 к этому варианту использования необходимости в onrun . PS: Надо было купить попкорн на всю ветку.

Я тоже думаю, что onrun или эквивалент (после запуска?) Является обязательным. Добавление сценария-оболочки и выполнение docker exec в контейнере просто ... уродливо.

IMO docker compose был отличным MVP для оркестровки контейнеров, чтобы убедить людей в простоте управления контейнерами. Возможно, нам, сообществу, следует считать, что он находится в «режиме обслуживания», поскольку готовые к работе решения для оркестровки (т.е. кубернеты) получили распространение. Когда у вас есть расширенные функции, такие как зависимости контейнеров, в сочетании с отсутствующими функциями, такими как «запускать эту вещь после того, как контейнер запущен», кажется, что это соответствует повествованию о том, что темп разработки просто остановился. По крайней мере, не очевидно, что эту функцию _ следует_ рассматривать вне сферы действия.

С Dockerfile не все легко сделать. Допустим, вы хотите добавить в контейнер свой собственный сценарий.
Например, возьмите контейнер mysql и попробуйте добавить простой скрипт для вызова API в случае какого-либо события.
Вы можете сделать это:

  • Измените Dockerfile mysql и добавьте свой собственный сценарий в контейнер перед точкой входа. Вы не можете добавить CMD в Dockerfile , так как это будет аргумент ENTRYPOINT .
  • Вы можете запустить контейнер, а затем скопировать свой сценарий в работающий контейнер и запустить его [ docker cp , docker exec ].

Вот почему я также думаю, что такая функция, как onrun , полезна, поскольку изменения Dockerfile не всегда достаточно.

Дамп, почему это закрыто? Рассмотрим ситуацию, когда вы используете официальный образ докера, такой как Cassandra, и вам нужно загрузить схему после ее запуска ... Придется реализовать свое собственное решение сценария bash для этого ... тьфу, это уродливо

@somebi похоже, что написание закрыто ...

Только мои два цента: я приземлился здесь, потому что в настоящее время мне приходится вручную включать модули Apache каждый раз, когда я запускаю контейнер (SSL не включен по умолчанию в Docker Hub wordpress image). Не конец света, но я надеялся запустить пару команд всякий раз, когда он поднимется, чтобы я мог просто легко поднимать и опускать контейнеры, не сталкиваясь с ними.

Только мои два цента: я приземлился здесь, потому что в настоящее время мне приходится вручную включать модули Apache каждый раз, когда я запускаю контейнер (SSL не включен по умолчанию в Docker Hub wordpress image). Не конец света, но я надеялся запустить пару команд всякий раз, когда он поднимется, чтобы я мог просто легко поднимать и опускать контейнеры, не сталкиваясь с ними.

Что ж, это можно легко решить, если вы создадите новый образ на основе образа wordpress, в котором есть необходимые вам модули. Затем используйте это вместо, например, файла докеров:

FROM wordpress:php7.1
RUN a2enmod ssl

Другим решением было бы загрузить Dockerfile wordpress и добавить в него активацию модуля. Затем создайте себе новый образ с помощью docker build. Например, это Dockerfile для wordpress 5.2 с php 7.1:

Wordpress dockerfile

вы можете включить больше модулей в строке 63 или запустить генерацию ssl.

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

Это было бы отличным дополнением к docker-compose!

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

Ответы, подобные тем, которые есть в этой теме, являются причиной того, что Kubernetes сохраняет _ "все" _ мони, которую производит Docker (технология), и это неплохо, надеюсь, кто-то скоро купит Docker (компанию) и изменит способ предложений / запросов сообщества приветствуются / анализируются ...

Я написал похожий критик, без каких-либо оскорбительных заявлений (это было похоже на _проекты с открытым исходным кодом, которые не являются полностью открытыми, чьи сопровождающие демонстративно игнорируют аргументы без какой-либо другой причины, кроме показа, сколько технического аргона они имеют_), он получил большую поддержку , и сообщение было удалено.

Это показывает, какие за этим стоят высокомерные люди.

Когда ваше сообщество требует чего-то в течение 4 лет, и вы (Докер) закрываете глаза, это показывает, что вы смотрите не в том же направлении, что и они: /

А теперь Докер сдался и был продан.
Потому что они не могли слушать ... они проиграли.

Позор - но эй-хо.

Очень жаль, что чего-то подобного не существует. Мне бы очень хотелось иметь возможность создавать хуки onFailure , которые могут выполняться, когда проверки работоспособности терпят неудачу.

т.е.

services:
  app:
    image: myapp:latest
    hooks:
      onFailure:
        - # Call a monitoring service (from the host machine) to tell it that the service is offline.

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

Редактировать:
Чтобы обойти это, я обновил точку входа своего контейнера, чтобы «обернуть» функцию мониторинга. т.е.

# /app/bin/run_with_monitor
#!/bin/bash
set -eE

updateMonitoringSystem() {
 # do something here... This is run from the container, though, unfortunately.
 if [[ $? -eq 1 ]]; then
  # Failed!
 else
  # All is good!
 fi
}

trap 'updateMonitoringSystem' EXIT

$@
# Dockerfile
....
CMD ["/app/bin/run_with_monitor", "./my-app"

Тем не менее, было бы неплохо сделать это _ без_ изменения образа.

: man_shrugging: Пришел искать эту базовую функциональность, которая есть у конкурента (Kubernetes), а вместо этого я обнаружил пожар в мусорном контейнере.

Очень жаль, теперь мне приходится поддерживать отдельные образы докеров для локального тестирования.

С Новым годом: roll_eyes:

image

@LukeStonehm и здесь. Требовалось выполнить ОДНУ команду после того, как контейнер был вставлен, но вместо этого был обработан горячим мусором. Мне действительно не хочется управлять своими собственными изображениями и файлами докеров, когда официальный образ дает мне 90% или больше пути.

Значительное количество программ полагается на определенные службы при запуске. Например, база данных MySQL или MongoDB.

Следовательно, в этих случаях нет разумного способа использовать docker-compose .

Вместо этого ожидается, что пользователи:

  • Узнайте, как писать Dockerfiles (и программировать)
  • Узнайте, как построить Docker images
  • Создайте Dockerfiles унаследовав от исходных изображений, добавив код, чтобы контейнеры ожидали друг друга
  • Регулярно проверяйте обновления безопасности базовых образов.
  • Регулярно изменяйте Dockerfiles чтобы применить обновления
  • Регулярно создавайте Docker images из этих Dockerfiles

И это отстой, потому что:

  • Вы тратите огромное количество времени на изучение вещей, которые в противном случае даже не понадобились
  • Вы регулярно тратите аппаратные ресурсы на создание и хранение Docker images самостоятельно или даже на загрузку / загрузку (вытягивание / отправку) их
  • Вы регулярно тратите время на написание этих Dockerfiles , их создание, тестирование, исправление и т. Д.
  • Вы потенциально ставите под угрозу безопасность своих изображений, потому что не знаете, что делаете
  • Вы теряете возможность запускать только официально проверенные / подписанные Docker images

Если бы у нас была проверка запуска, все это не понадобилось бы, и мы могли бы просто изменить image: mysql:8.0.18 на image: mysql:8.0.19 когда захотим, и готово!

На самом деле это то, что сейчас происходит в реальном мире:

  • Люди создают свои собственные Dockerfiles внося изменения, чтобы работать с docker-compose
  • Они создают свои образы один раз
  • И не исправляйте их регулярно
  • Хакеры счастливы

И вы не можете сказать, что docker-compose должен «делать что-то одно», потому что он уже делает почти все. В том числе извлечение и построение изображений, что еще более важно, указание зависимостей с помощью свойства depends_on . Речь идет даже не о реализации совершенно новой функции, а о передаче другого параметра в docker .

@ мусорщик-докер @crosbymichael @dmcgowan @ebriney @ehazlett @eunomie @guillaumerose @jeanlaurent @justincormack @lorenrh @manishtomar @olegburov @routelastresort @spencerhcheng @StefanScherer @thaJeztah @tonistiigi @ulyssessouza @aiordache @ Крис-@ndeloof кроны
Пожалуйста, пересмотрите эту функцию или давайте, по крайней мере, обсудим ее как следует.

Техника task service мне очень хорошо подходит на данном этапе, но у меня есть свои особенности. Мы широко применили шаблон в наших файлах для создания миграции и инициализации приложений. но я согласен с тем, что лучший параметр «depends_on», который ожидал успешной проверки работоспособности или успешного выхода / завершения задачи, сделал бы многие задачи проще и надежнее.

Это действительно было бы полезным дополнением.

Я думаю, стоит подчеркнуть, что Kubernetes имеет эту функциональность через жизненный цикл postStart.

k8s! = docker-compose. Неправильный канал

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

Хорошие новости!!

Думаю, Докер нас слышал (по этому вопросу и по некоторым другим). https://www.docker.com/blog/announcing-the-compose-specification/

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

Хорошие новости!!

Думаю, Докер нас слышал (по этому вопросу и по некоторым другим). https://www.docker.com/blog/announcing-the-compose-specification/

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

Кто-нибудь еще предлагал это изменение? Список рассылки пока недоступен, поэтому я думаю, что следующее лучшее место здесь: https://github.com/compose-spec/compose-spec

Я не вижу проблемы, описывающей эту проблему, но не уверен, что это подходящее место ...

Изменить: я открыл проблему на https://github.com/compose-spec/compose-spec/issues/84.

Вы можете использовать HEALTHCHECK, чтобы сделать что-то еще, как в следующем примере:

Код

Dockerfile

FROM ubuntu

COPY healthcheck.sh /healthcheck.sh
RUN chmod a+x /healthcheck.sh

HEALTHCHECK --interval=5s CMD /healthcheck.sh

CMD bash -c 'set -x; set +e; while true; do cat /test.txt; sleep 3; done'

healthcheck.sh

#/usr/bin/env bash

set -e

FIRST_READY_STATUS_FLAG='/tmp/.FIRST_READY_STATUS_FLAG'

# Health check

echo 'Run command to validate the container status HERE'

# On success
if [ ! -f "${FIRST_READY_STATUS_FLAG}" ]; then
  # On first success...
  touch "${FIRST_READY_STATUS_FLAG}"

  # Run ON_RUN on first health check ok
  if [ ! -z "${DOCKER_ON_RUN}" ]; then
    eval "${DOCKER_ON_RUN}"
  fi
fi
  1. Запустите _health check_.

    • В случае неудачи выходит из скрипта с кодом выхода 1 .

    • Если _health check_ в порядке, сценарий продолжится.

  2. Если это первая _ проверка работоспособности ОК_ и существует переменная среды DOCKER_ON_RUN , выполните ее.

пример

docker-compose.yml

version: "3.7"

services:
  test:
    build:
      context: .
    image: test/on-run
    environment:
      DOCKER_ON_RUN: echo x >> /test.txt

Вы можете использовать переменную среды DOCKER_ON_RUN для передачи настраиваемой команды для выполнения после запуска.

Результат исполнения

docker-compose build
docker-compose up

Вывод:

Creating network "tmp_default" with the default driver
Creating tmp_test_1 ... done
Attaching to tmp_test_1
test_1  | + set +e
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
  • Вы можете видеть ошибку cat: /test.txt: No such file or directory пока _health check_ не будет готова.
  • Вы можете увидеть только один x внутри /test.txt после запуска .

Надеюсь, это поможет кому-то.

Редактировать 1

Если вам не нужна _health check_, вы можете использовать остальную часть скрипта.

@ reduardo7
Спасибо за обходной путь.
Просто хочу добавить, если вам нужно запустить первую команду, например, для создания пользователей и т. Д., Вы можете смонтировать том для touch "${FIRST_READY_STATUS_FLAG}"

Многие из этих решений являются допустимыми обходными путями к этой проблеме. Например, создание сценария точки входа также может решить эту проблему:
ENTRYPOINT ["./entrypoint.sh"]

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

  • перед созданием
  • до начала
  • после запуска
  • перед разрушением
  • даже после уничтожения
  • и т.д ...

Я знаю, что не все вышеперечисленное имеет смысл, но надеюсь, что вы уловили картину, потому что в этом суть.
Это также может быть включено в docker-compose с помощью такой директивы, как:

lifecycle:
    before_start: "./beforeStartHook.sh"
    after_destroy: "./afterDestroyHook.sh"

или даже так:

hooks:
    before_destroy: "./beforeDestroyHook.sh"
    before_create: "./fixFsRights.sh"

Я не могу перезаписать файл, для которого требуется разрешение root, с помощью сценария перехвата или сценария начальной загрузки, поскольку мы запускаем контейнер как пользователь без полномочий root

Ух ты, такой базовый функционал так и не реализован.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги