company_banner

Полная автоматизация среды разработки с помощью docker-compose

Автор оригинала: Andrew Orsich
  • Перевод

Согласно данным, которые представил на Dockercon 2016 CEO компании Docker Бен Го́луб (Ben Golub), количество работающих в контейнерах Docker приложений за последние два года выросло на 3100%. Docker обеспечивает функционирование 460 тысяч приложений по всему миру. Это невероятно!


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


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


Проблема


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


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


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


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


Быстрый старт с docker-compose


Docker-compose — это простой инструмент, который позволяет запустить несколько докер-контейнеров одной командой. Перед тем как окунуться в детали, я должен рассказать о структуре проекта. Мы используем monorepo, и кодовая база каждого сервиса (веб-приложение, API, фоновые обработчики) хранится в своей корневой директории. У каждого сервиса есть описывающий его зависимости Docker-файл. Пример такой структуры можно увидеть в нашем демонстрационном проекте.


Давайте начнем с автоматизации простого приложения, которое зависит от MongoDB и небольшого сервиса на Node.JS. Конфигурация для docker-compose находится в файле docker-compose.yml, который обычно помещается в корневую директорию проекта.


version: '2'  
services:  
  web:
    build:
      context: ./web
      dockerfile: Dockerfile.dev
    volumes:
      - "./web/src:/web/src"
    ports:
      - "8080:8080"
  mongo:
    command: mongod
    image: mongo:3.2.0
    ports:
      - "27100:27017" # map port to none standard port, to avoid conflicts with locally installed mongodb. 
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Для запуска проекта нужно выполнить лишь одну команду:


$ docker-compose up

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


  1. context: ./web — таким образом указывается путь к исходному коду сервиса в рамках monorepo.
  2. dockerfile: Dockerfile.dev— для окружений разработки мы используем отдельный Dockerfile.dev. В production исходный код копируется прямо в контейнер, а для разработки подключается в виде тома. Поэтому нет необходимости заново создавать контейнер при каждом изменении кода.
  3. volumes: - "./web/src:/web/src" — таким образом каталог с кодом добавляется в docker в виде тома.
  4. Docker-compose автоматически связывает контейнеры друг с другом, поэтому, например, веб-сервис может получить доступ к mongodb по имени: mongodb://mongo:27017

Всегда используйте аргумент --build


По умолчанию, если контейнеры уже есть на хосте, docker-compose up их не пересоздает. Для принудительного выполнения этой операции используется аргумент --build. Это необходимо, когда меняются сторонние зависимости или сам Docker-файл. Мы приняли за правило всегда выполнять docker-compose up --build. Docker отлично кэширует слои контейнера и не станет их пересоздавать, если ничего не изменилось. Постоянное использование --build может на несколько секунд замедлить загрузку, но предохраняет от неожиданных проблем, связанных с работой приложения с устаревшими сторонними зависимостями.


Совет: вы можете абстрагировать запуск проекта с помощью простого скрипта:


#!/bin/sh
docker-compose up --build "$@"  

Такой прием позволяет по необходимости менять опции и используемые при запуске инструменты. А можно просто выполнить ./bin/start.sh.


Частичный запуск


В примере docker-compose.yml одни сервисы зависят от других:


  api:
    build:
      context: ./api
      dockerfile: Dockerfile.dev
    volumes:
      - "./api/src:/app/src"
    ports:
      - "8081:8081"
    depends_on:
      - mongo

В этом фрагменте сервису api требуется база данных. При использовании docker-compose можно указать имя сервиса, чтобы запустить только его: docker-compose up api. По этой команде запустится MongoDB и после него сервис API. В больших проектах такие возможности могут пригодиться.


Эта функциональность полезна, когда разным разработчикам нужны разные части системы. Например, специалисту по фронтэнду, который работает над landing-страницей, не нужен проект целиком, достаточно лишь самой landing-страницы.


Ненужные логи в >/dev/null


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


  mongo:
    command: mongod
    image: mongo:3.2.0
    ports:
      - "27100:27017"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    logging:
      driver: none

Несколько файлов docker-compose


После запуска команды docker-compose up она по умолчанию ищет файл docker-compose.yml в текущей директории.


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


docker-compose --file docker-compose.local-tests.yml up  

Так зачем же нужны несколько файлов конфигурации? В первую очередь для разбиения составного проекта на несколько подпроектов. Радует, что сервисы из разных compose-файлов все равно могут быть связаны. Например, вы можете поместить в один файл docker-compose контейнеры, связанные с инфраструктурой (базы данных, очереди и т. д.), а в другой — контейнеры, связанные с приложениями.


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


Мы используем различные виды тестирования: unit, integrational, ui, linting. Для каждого сервиса разработан отдельный набор тестов. Например, интеграционные и UI-тесты требуют для запуска api- и web-сервисы.


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


version: '2'  
services:  
  api-tests:
    image: app_api
    command: npm run test
    volumes:
      - "./api/src:/app/src"
  web-tests:
    image: app_web
    command: npm run test
    volumes:
      - "./web/src:/app/src"

Наш compose-файл с тестами зависит от основного docker-compose-файла. Интеграционные тесты подключаются к development-версии api, UI-тесты — к web frontend. Тестовый compose-файл лишь запускает контейнеры, созданные в основном docker-compose-файле. Если нужно запустить тесты только для одного сервиса, можно использовать частичный запуск:


docker-compose --file docker-compose.local-tests.yml up api-tests  

Эта команда запустит только тесты для api.


Префиксы имен контейнеров


По умолчанию всем контейнерам, запущенным с помощью docker-compose, присваивается префикс в виде имени родительской директории. Имя директории в различных средах разработки может меняться. Из-за этого Docker-compose-файлы с тестами, о которых мы говорили ранее, могут перестать работать. Мы используем префикс (app_) для контейнеров в основном файле docker-compose. Для согласованной работы конфигурации в различных средах мы создали специальный .env-файл в директории, в которой запускаем docker-compose:


COMPOSE_PROJECT_NAME=app  

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


Заключение


Docker-compose — это полезный и гибкий инструмент для запуска ПО, используемого для работы над проектами.


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


1) установить Docker и Docker-compose,
2) скопировать репозиторий GitHub,
3) выполнить в терминале команду ./bin/start.sh.


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


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


Оригинал: Fully automated development environment with docker-compose

Southbridge
567,13
Обеспечиваем стабильную работу серверов
Поделиться публикацией

Комментарии 38

    +1

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


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

      0
      Посоветуйте пожалуйста.
      Я делаю сайты на nginx+php7-fpm, mariadb, sphinx. Мне docker как-то может помочь?
      Как перенести список пакетов с VPS на Debian на другой такой же сервер. Ну чтобы на другом сервере поставились такие же пакеты с такой же конфигурацией, такой софт есть?
        0
        Докер для этого идеален, сделали образ и потом с него запускаете контейнер на любом сервере, где установлен докер.
          0

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

            0
            Ну так я и есть админ, причём я «ленивый» админ, поэтому уже больше двух лет использую докер где только можно. Вот небольшой список, что у нас крутится в контейнерах:
            bind
            icinga2
            icinga2 docker monitoring — я тут недавно писал про это статью
            git
            horde
            keybox
            mariadb
            forum
            backup(nodebackup) — это для бэкапа контейнеров.
            postgrel
            proxy
            vpn

            Cписко несколько больше, но я его не могу публиковать плюс некоторые вещи повторяются для разных серверов
          0

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


          Если на продакшене докер запускать не хочется или не можется, то крайне желательно иметь скрипты разворачивания продакшена с нуля. Это могут быть кофиги утилит систем типа ansible или puppet, а могут быть простые bash-скрипты (как у нас). Главное, держать их в синхронизации с файлами докера.

          0
          Мы похоже делаем.
          У нас есть гит репозиторий, где находятся все конфигурации для контейнеров. Для каждого контейнера своя папка, в ней лежат два файла — docker-compose.yml и env. Во втором (env) написано на каком сервере должен разворачиватся контейнер. Когда делается комит, то git-runner раскладывает папки по серверам.
          Также в этом репозитории лежит Vagrantfile с которого можно запустить виртуальную машину и уже в ней что-то потестировать.
            0

            А в первом что? Как контейнеры друг с другом связываете?

              0
              В смысле что? Там конфигурация контейнера/ов. Они (папки) больше логически поделены, чем на контейнеры.
              К примеру docker-compose.yml для redmine.
              redmine:
                image: redmine:3.2
                hostname: redmine.example.local
                links:
                  - mysql:mysql
                ports:
                  - "192.168.40.203:3000:3000" # http
              #    - "192.168.33.10:3000:3000" # vagrant-http
                volumes:
                  - /etc/localtime:/etc/localtime:ro
                  - /etc/timezone:/etc/timezone:ro
                  - /a/data/redmine.intern/redmine:/usr/src/redmine/files
                  - ./config/configuration.yml:/usr/src/redmine/config/configuration.yml
                restart: unless-stopped
                labels:
                  nextfullbackup: "1M"
                  noffullbackup: "2"
                  backup: "/a/data/redmine.intern"
                  strategy: "off"
              
              mysql:
                image: mysql:5.7
                ports:
                  - "192.168.40.203:3306:3306" # mysql-database
              #    - "192.168.33.10:3306:3306" # vagrant-mysql-database
                volumes:
                  - /etc/localtime:/etc/localtime:ro
                  - /etc/timezone:/etc/timezone:ro
                  - /a/data/redmine.intern/db:/var/lib/mysql
                environment:
                  - MYSQL_ROOT_PASSWORD=PASS
                  - MYSQL_DATABASE=redmine
                command: mysqld --lower_case_table_names="1"
                restart: unless-stopped
              

              «Labels» нужны для бэкапа, через них моя программа находит, какие контейнеры надо сохранять.
                0
                Они (папки) больше логически поделены, чем на контейнеры.

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

                  0
                  Можно ещё сделать сеть и к этой сети подключить два контейнера из разных docker-compose файлов.
                  Это будет в первом:
                      networks:
                        - dbnet
                      external_links:
                        - mariadb
                  


                  А это во втором:
                      networks:
                        default:
                          aliases:
                            - mariadb
                  

                  Для этого нужна вторая версия docker-compose файла
                  version: "2"
                  
                    0

                    Хорошо быть админом :(

                    0
                    Можно сделать сеть, как указал выше de1m, можно назначать Докер-имена любым IP или домейнам (допустим, если ваше приложение должно обращаться к каким-то внешним API).
              0
              Есть смысл еще использовать параметр -d, для запуска в background-режиме, bash-сессия может прерваться, а с ней и запущенный docker-compose
                +1
                Docker в продакшене с проброской портов «27100:27017»? Попробуйте фаерволом закрыть все порты, кроме нужных, и подключиться извне к порту 27100. Будете удивлены. Чтобы закрыть порт от посторонних глаз, я делал проброску портов так: «172.17.0.1:27017:27017», где 172.17.0.1 — интерфейс docker0.
                  0

                  Название поста: "Полная автоматизация среды разработки с помощью docker-compose". Ни слова о продакшене, чисто для локального запуска всё.

                  0
                  Вот небольшой список, что у нас крутится в контейнерах:
                  bind
                  git

                  а какой глубокий смысл запускать git/bind в докере? Вы их часто обновляете или вам часто приходится разворачивать соотв окружения на других серверах? Можно use-case так сказать, преимуществ использования докер конкретно в этих случаях?

                  Вообще заметил в последняя время плохую тенденцию — запускаем все в докере ибо это стильно/модно/молодежно. Как в свое время была тенденция — переписываем все gnu утилиты на go.
                    0
                    Докер — это не только способ доставки приложений до железа, но и способ документирования где и что подкручено (есть, конечно, исключения, когда это непрозрачно, например, образ выкатывается из tar-архива).

                    Это не отменяет того факта, что прежде чем что-то (хоть докер, хоть не докер) использовать нужно оценивать потенциальную выгоду и затраты.
                      0
                      Докер — это не только способ доставки приложений до железа, но и способ документирования где и что подкручено (есть, конечно, исключения, когда это непрозрачно, например, образ выкатывается из tar-архива).
                      для этого вроде как есть системы управления конфигурациями — chef, puppet, ansible,…

                      Просто стало интересно, зачем запускать тот же bind и уж тем более git в докере, какие преимущества мы получаем?
                        0
                        Я напишу только три плюса, но наверное их больше(это всё со стороны администратора).
                        1. В обоих случаях у меня получается чёткое разделение на систему и данные, то есть, когда я делаю бэкапы, то я знаю, что мне нужна только одна, ну или несколько определённых папок и всё.
                        Когда у меня к примеру сгорит сервер, то я просто беру новый ставлю на него линукс и докер, заливаю бэкап (один только) и всё, у меня снова всё работает, вообще всё работает что было.
                        2. Здесь только про гит — это обновления. Когда выходит новая версия, я просто скачиваю новый образ, запускаю с него контейнер и у меня уже актуальная версия.
                        3. Касается всех — это мониторинг. То есть у меня сделано так, что я вижу статус каждого контейнера, а так как каждый контейнер это один процес. То я соответственно вижу, если не работает контейнер, то это значит, что не работает какой-то сервис.
                        Причём каждый контейнер автоматически регестрируется в мониторинге и мне ничего не надо делать. Раньше без докера было по другому и было сложнее, в винде всё ещё приходится по старинке делать.

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

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

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

                            0
                            Может, потому что хардкор-СУБД стремятся сами управлять памятью, процессорами и дисковым пространством? В этом случае, в «боевом режиме» прослойка Докера будет несколько снижать производительность. Ну и, разумеется, все рабочие файлы надо размещать на томах (volumes) а не в ФС Докера.
                              0

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

                            0
                            1. Опять таки — для этого есть SCM. Ведь все равно вам где то надо хранить персистентные данные при использовании докера.
                            2. А в случае не Docker вам достаточно yum update/apt-get update или что вы там используете. Единственный плюс который я вижу — ваш дистрибутив не поддерживает нужной вам версии ПО, а собирать свой rpm/deb накладно и/или невозможно. Но это довольно таки редкий случай.
                            3. Что касается регистрации возможно, но в том же Zabbix отлично работает auto discovery и без всяких докеров

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

                            я тоже самое вижу и без докера. Если я мониторю smtp, pop3, imap4, mysql на одном сервере, то когда перестает работать определенный сервис я это вижу. Или я не понял, что вы хотели сказать.
                              0
                              мне не охота спорить, поэтому вы правы, а я, соответственно, нет.
                              Поэтому я пойду посыплю голову пеплом и верну все мои серверы на четыре года назад.
                                0
                                да никто не спорит, просто хотел понять в чем профит, мб я что то упускаю или чего то не знаю о докере ;)
                                  0

                                  Докер из коробки показывает состояние запущенных процессов. Если какой-то процесс даже сегфолтится, то он не пропадает из списка, а переходит в состояние exited (по памяти). То есть грубый мониторинг можно сделать по простой формуле "все процессы должны быть в состоянии running" ничего не зная о том, что это за процессы.

                                    0
                                    Я исходил из того, что если к примеру процес «nginx» в контейнере остановится, то соответственно остановится и сам контейнер. Соответственно, если я вижу, что контейнер не работает, то тогда и моя страница или прокси тоже не работает.
                                    Потом чтобы каждый контейнер не прописывать в мониторинге, я сделал программу (nodejs) которая во-первых сравнивает наличее контейнеров на докер хосте и в мониторинге и удаляет, либо добавляет лишнее. Во-вторых смотрит все ли они работают.
                                      0

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

                              0
                              Позвольте вопрос. Какие данные и как вы бэкапите? Ведь простое копирование файлов в сторону, как правило, плохая идея из-за различных кешей-буферов и прочего.
                                0
                                Я использую для этого nodebackup, специально писал для удобного сохранения данных из контейнеров, а также нормальных серверов. Есть также готовый докер образ, которому надо только подсунуть конфигурацию, crontab файл и ssh key. Там под капотом используется duplicity.

                                Пример (посмотрите выше, там где пример для redmine):
                                У меня для redmine есть один docker-compose.yml файл в нем описаны два контейнера, причём один из них это СУБД, то есть когда это всё работает, сохранять не желательно. Надо выключить контейнер, также контейнеры связаны между собой.
                                Вот эта часть в docker-compose.yaml говорит, что нужет бэкап
                                  labels:
                                    nextfullbackup: "1M"
                                    noffullbackup: "2"
                                    backup: "/a/data/redmine.intern"
                                    strategy: "off"
                                

                                Nodebackup может через docker.sock посмотреть какой контейнер надо сохранять. Если в «strategy:off», то это означает, что перед тем, как начать делать бэкап, то нужно выключить контейнеры, также тот, который слинкован. После этого он смотрет на путь в «backup» и тут уже включается duplicity. После этого контейнер снова стартует.
                                Если посмотрите выше, то видно, что эта папка примонтирована в оба контейнера.

                                Есть варианты, где контейнер не надо выключать, к примеру bind. Тогда соответственно «strategy: on». Там на самом деле ещё много можно опций писать.

                                Есть ещё один вариант, когда к примеру большая СУБД, но на долго контейнер нельзя выключать. Тогда используются возможности файловой системы (btrfs или сephfs) и делается снапшот.
                                То есть nodebackup выключает контейнер, потом снапшот, потом контейнер снова включается, а дальше nodebackup спокойно делает бекап со снапшота, после чего его стирает.

                                PS Извеняюсь, что так растёкся мыслью, просто я вроде как написал хорошую програму для докер контейнеров, а никто не знает. ))
                                  0
                                  Спасибо за развернутый ответ. Я интересовался, потому что сам не смог найти ответ на достаточно простой вопрос: как сложить данные в архив, чтоб при этом целостность данных не была нарушена. В итоге, для файлов, написал свой велосипед, который делает снапшот и запаковывает данные в tar-архив. Плюсом к этому logrotate, который занимается ротацией архивов.

                                  duplocity — вещь хорошая, но сама делать снапшоты не умеет.

                                  Велосипед, если кому интересно
                              0
                              Тут наверно правильнее будет сказать, что делает docker лучше чем условный chef.
                              Строго говоря, критерий лучшести каждый определяет самостоятельно. И тогда кому-то будет удобнее docker, кому-то условный chef.
                              Но в чем безусловно плюс, это более формальное разделение ответственности между артефактом, отвечающим за бизнес-логику, и артефактом, отвечающим за обслуживание.

                              Например за условный bind отвечает одна команда.
                              За железо — другая.
                              За сбор логов — третья.
                              У каждой свои инструменты — docker, chef, etc. У каждой — свои репозитарии (vcs). Взаимодействие осуществляется по декларативно прописанным интерфейсам: файлы, порты, и т.д.
                                0
                                Докер позволяет ставить любые версии софта, не ломая голову над управлением общими зависимостями.
                            0
                            Можно одной-двумя командами перейти на другую версию/конфигурацию — а потом вернуться, что-то пойдет не так. При этом ничто другое в системе не поломается.
                            0

                            Предположим есть builder контейнер, который строится и потом запускается через run, а результат его работы надо положить в другой pro контейнер. Ведь не будешь же класть весь NodeJS со всеми модулями из билдера в продакшен образ, где только Nginx нужен. Что то типа этого тикета и схожий кейс там же.


                            Может ли compose помочь с этим как-то?

                              0
                              Я так понимаю это просто повтор перевода https://habrahabr.ru/post/322440/?
                                0
                                Да, выходит, что так.

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

                              Самое читаемое