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

С одной стороны, Docker очень универсальный инструмент, его можно легко и эффективно использовать для решения огромного количества задач. Он понятен и кажется, что все элементарно. Но с другой стороны, если не потратить свое время и ресурсы, чтобы “прокачаться” в грамотном его использовании, вы, скорее всего, переусложните простые вещи. И конечно же будете считать что вы правы, а Docker это бездарная громоздкая фигня, не подходящая для решения вашей уникальной задачи.

Обычно, в стандартной компании, процесс работы над любой задачей выглядит так:

  1. Делается git push с нашим коммитом
  2. Триггерится какая-то система, будь то Jenkins, TeamCity и т.п.
  3. Запускается пайплайн/job, в котором происходит скачивание сторонних библиотек, компиляция проекта, прогон тестов
  4. Создается docker образ с собранным проектом (ADD. .) и пушится в удаленный docker registry
  5. Каким-нибудь образом на удаленном сервере делается docker pull (chef, puppet, вручную через docker-compose) и запускается контейнер.

Интуитивно я всегда чувствовал, что это все как-то чересчур сложно. Этот процесс гордо называют CI/CD и я уже устал от таких умников, которые ничуть не сомневаются в том, что это самый простой путь.

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

Что мне НЕ нравится в этом подходе.

  1. Единственный способ развернуть систему на удаленном сервере — это пройти через все 5 шагов.
  2. В шаге 3 могут понадобиться ключи доступа к приватным библиотекам. Процесс может быть долгим, если не настроено кеширование ранее скачанных библиотек.
  3. Нужно подготовить Dockerfile, определиться с образом (FROM …), определиться как мы будет тегировать образ и нужны доступы к репозиторию, в который мы будем пушить образ.
  4. Нужен свой репозиторий, настроить https. Ведь docker client работает только по https.


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

Но не много ли раз упоминается слово Docker уже на стадии релиза?

Задумайтесь: зачем мы тащим весь этот Docker раньше времени? Потому что считается, что в контейнере удобно и “Ну нормально же все было, работает. Чего ты начинаешь то?”.
Так вот, для таких людей я могу сказать — докер контейнеры это не панацея и не единственная среда, в которой может исполняться ваше приложение. Проект написанный на python, php, js, swift, scala/java, т.д. можно запускать еще на:

  • удаленной виртуальной машине
  • на локалхосте без всякой виртуализации и docker контейнеров.

Внезапно :)

Давайте представим, что мы делаем сервис, который будет работать на nodeJS.

Результатом этого проекта (или как я называю ‘артефактом’) будет набор js файлов (сам сервис) + node_modules (сторонние библиотеки, которые используются в сервисе).

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

Как вам такая идея:

  1. Делаем .tar.gz с нашим проектом и заливаем его в … удаленное хранилище артефактов! (Еще такие хранилища называют “бинарный репозиторий”).
  2. Говорим url по которому могут скачать наш сервис и начать тестировать.

Дальше тестировщики могут запустить сервис или локально у себя, если у них все есть, или сделать Dockerfile, в котором будет скачивание артефакта и просто запустить контейнер. Ну или еще как-нибудь.

Сразу скажу, если вы не хотите чтобы тестировщики запускали docker контейнеры и вообще “это не их работа” по запуску, то используйте инструмент, который будет собирать образы как только новые артефакты появятся в бинарном репозитории (используйте web hook, гоняйте периодически по крону).

Сейчас из бинарных репозиториев есть:

  • Sonatype Nexus
  • Artifactory

Нексус простой в использовании, в нем куча разных репозиториев, которые можно создать (npm, maven, raw, docker) так что я использую его.

Это же чертовски простая идея, почему я нигде про это не читал? В интернете не счесть статей “как по git push где-то разворачивается контейнер в каком-нибудь kubernetes”. От таких сложных алгоритмов волосы встают дыбом.

Цель данной статьи, сказать — не нужно в одном процессе делать сборку проекта и добавлением его в докер образ.

Разделяете и властвуйте!

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

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

Удачи вам в запуске ваших проектов!

Комментарии (81)


  1. usego
    10.03.2019 11:49
    +11

    А через 3 года опсы смотрят на загаженные всем чем сервера и не понимают, что с ними делать. Спасибо, не надо. Как хорошо, что эти времена уже в прошлом. CI/CD настраивается один раз и работает в единой экосистеме доставки софта. А главное — это разделение зон ответственности. Поделия программеров — отдельно, экосистема их запуска — отдельно.


    1. kondaurovDev Автор
      10.03.2019 15:15

      Рад за вас что у вас CI/CD работает как надо, все тестируется, запускается без проблем! Какую билд систему используете? jenkins? circle? gitab? В чем запускаете процесс сборки, в контейнерах или на хостах? А кешируется какими то внутрненними директивами? А как воркеры настраивали? А docker репозиторий как поднимали, свой?


      1. usego
        10.03.2019 15:58
        +4

        В данный момент selfhosted Гитлаб с раннерами, которые собирают докера либо через docker build, либо через Dapp (werf). Последняя тулза как раз для кеширования тяжелых стадий типа npm install. Репозиторий свой в паре с гитлабом.


        1. gecube
          10.03.2019 23:25
          -1

          Честно скажу, что я по прошествии года использования Гитлаба понял, что никакой ценности в selfhosted нет.
          Аргументы:
          1. ценники одинаковые, что на selfhosted, что на облачный
          2. облачный даже стабильнее работает — не нужно думать об обновлениях и т.п. Но есть риск попасть под блокировки РКН. Или, например, в ситуацию DROP DATABASE (уже было).
          3. На бесплатном тарифе 2000 минут на shared runners. Это достаточно для любого маленького проекта. Если мало ли не хватает — можно ВСЕГДА подключить runners из своего закрытого контура и решить две задачи: снять лимит на время сборок и деплой в закрытый контур
          4. Единственное серьезное ограничение облачного гитлаба — размер репозиториев и docker registry. Но если у вас репозиторий больше 2ГиБ, то прямо скажу, что что-то делаете не так. И docker registry гитлабовский подходит ТОЛЬКО для хранения временных образов. Для production образов очень желательно сделать свой отдельный репозиторий.


          1. usego
            11.03.2019 09:25

            Я начал с selfhosted, что бы заменить свой же SVN, облако даже не рассматривал. В результате сейчас весь гитлаб — это ансибле скриптец строк на 50 вместе с репозиторием. Апгрейдится элементарно, заменой тага. Стабилен, проблемы помню только пару раз были именно при апгрейдах, не сразу поднимался бывало, но за последний год такого уже не помню.


            1. gecube
              11.03.2019 10:51

              Отлично. Опять минусуют (((( Как обычно.

              Вы расскажите — ценность self-hosted для вас в чем?
              Я свою позицию выше описал.

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

              В целом — да, согласен. Если поднимать omnibus в докере, то стартует достаточно быстро и SLA по его доступности даже с еженедельными обновлениями вряд ли будет хуже 99.9%


              1. usego
                11.03.2019 11:12

                У меня не стоит вопрос selfhosted vs cloud, так как selfhosted поднял изначально и это совершенно не вызывает каких либо проблем, соответственно cloud и не рассматриваю вообще, так как профита для меня лично он не добавит.


              1. ProFfeSsoRr
                11.03.2019 14:33

                ценность self-hosted для вас в чем?

                Вы ж сами выше написали — риск блокировок, DROP DATABASE. Этого недостаточно, чтобы пользоваться self hosted?


                1. gecube
                  11.03.2019 14:38

                  Нет, недостаточно. Как будто DROP DATABASE не может случиться на self-hosted. Я даже более того гарантирую, что селф-хостед гитлаб НИКТО не будет делать в HA-режиме. Максимум — с регулярными бекапами на отдельный сервер/сторедж.
                  Касательно блокировок — бизнес может встрять по причине отключения кучи других сервисов и ГитЛаб из них не самый важный.

                  Риск утечки исходных кодов — да, он не эфемерен. Но тут вопрос доверия. Доверия к тем же облачным или нет российским провайдерам, к которым придут силовики и коды точно так же утекут.

                  В общем, если кратко — self-hosted vs cloud — это больше не технический вопрос, а административный.


                  1. ProFfeSsoRr
                    12.03.2019 05:00

                    Может. Но, что еще важнее, я сам точно знаю время, за которое разверну бекап, и вместо «там у них авария, сидим ждем неизвестно сколько» скажу «тут у нас авария на полчаса».


      1. Yeah
        11.03.2019 01:18
        +1

        Какую билд систему используете?

        CircleCI


        В чем запускаете процесс сборки, в контейнерах или на хостах

        В контейнерах


        А кешируется какими то внутрненними директивами?

        кешируется npm i через внутренний механизм кеширования CircleCI


        А как воркеры настраивали?

        Какие воркеры?


        А docker репозиторий как поднимали, свой?

        AWS ECR


  1. powerman
    10.03.2019 12:01
    +7

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


    Что касается сложностей настройки CI/CD, то, честное слово, один раз настроить и дальше выкатывать нужную версию проекта на сервера одним git push намного проще, чем делать по описанной Вами схеме, которая подразумевает либо ручные операции (кто-то заливает tar.gz, кто-то его скачивает, после чего куда-то как-то устанавливает), либо написание для всех этих операций кучки специализированных скриптов.


    Очевидные недостатки подхода с tar.gz:


    • нет понимания и гарантий, откуда взялось его содержимое: кто и как его подготовил, соответствует ли оно конкретному коммиту в репо, вносились ли в содержимое архива ручные изменения, etc.
    • нет повторяемости сборок: tar.gz подготовленные разными разработчиками в разное время из одного и того же состояния репо проекта могут отличаться (по множеству причин)
    • нет гарантии, что один и тот же tar.gz будет у всех (разработчиков/тестировщиков/в проде) работать одинаково, т.к. если у него внутри не статически собранный бинарник то работа проекта может сильно зависеть от окружения, в котором его запускают, от версии node/python/etc., версий установленных глобально библиотек, версий внешних утилит запускаемых проектом (последнее, кстати, даже на статическом бинарнике скажется)

    В результате на решение проблем вызванных вышеописанными причинами уходит намного-намного-намного больше времени, чем на разовую настройку CI/CD через докер и установку докера всем разработчикам/тестировщикам.


    1. kondaurovDev Автор
      10.03.2019 12:16

      Спасибо за комментарий!
      1. Если вы сделаете docker pull то вы тоже не знаете кто подготовил образ, были ли у него ручные изменения и т.п. Образ может быть вообще битым, если есть права на запись в docker registry то можно запушить хоть hello-world образ под тегом вашего проекта и никто не заметит пока не спулит образ.
      2. это по сути первый пункт, запушить можно что угодно, разве нет?
      3. можно в образ с nodejs запихнуть проект написанный на несовместимой с данной версией ноды. Когда будет docker build то вы не получите никаких ошибок (если у вас не исполняются какой нибудь код конечно).
      Конечно нет гарантий что tar.gz будет содержать то что нужно, но и docker registry не накладывает никаких ограничений. Если все одинаково, зачем тогда париться с докерной экосистемой?


      1. powerman
        10.03.2019 12:29
        +4

        Если вы сделаете docker pull то вы тоже не знаете кто подготовил образ

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


        это по сути первый пункт, запушить можно что угодно, разве нет?

        Нет. Фишка в том, что CI собирает проект тоже внутри докер-контейнера, поэтому при повторе сборки на CI через месяц будет получен точно такой же результат — ведь проект собирался из тех же исходников и всё это происходило в том же контейнере.


        Это можно сломать, если процесс сборки включает в себя выкачивание из инета "свежих" версий зависимостей проекта. Но тут ССЗБ — если нужны повторяемые сборки нужно либо вендорить зависимости, либо использовать менеджер пакетов гарантирующий повторяемость сборок (lock-файлами, или в стиле модулей Go).


        можно в образ с nodejs запихнуть проект написанный на несовместимой с данной версией ноды

        И зачем это делать? Кроме того, обычно собираемый образ тестируется перед релизом, на то оно и CI — или Вы и тесты не пишете? Так что корректно настроенный CI не зальёт в докер регистри неработающий образ. А любой залитый образ — будет одинаково работать везде.


        1. kondaurovDev Автор
          10.03.2019 12:44
          -1

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

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

          Нет. Фишка в том, что CI собирает проект тоже внутри докер-контейнера, поэтому при повторе сборки на CI через месяц будет получен точно такой же результат — ведь проект собирался из тех же исходников и всё это происходило в том же контейнере.

          Не согласен, я видел мало компаний который запускали сборки в докер контейнере, обычно запускают просто на хосте.
          И зачем это делать? Кроме того, обычно собираемый образ тестируется перед релизом, на то оно и CI — или Вы и тесты не пишете? Так что корректно настроенный CI не зальёт в докер регистри неработающий образ. А любой залитый образ — будет одинаково работать везде.

          Эх, если бы пайплайны были такие как вы говорите. Мало кто делает тесты, обычно пакуют что сбилдилось прям в образ и пушат его.
          Я не говорю что нужно отказаться от докера, нет! Просто пусть образы будут собираться отдельным сервером, сделать что то типа automated builds в докер хабе


          1. powerman
            10.03.2019 14:23

            Я тоже буду знать кто может заливать файлы.

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


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

            Извините, но меня как-то не очень волнует Ваш личный опыт. Из популярных CI-сервисов и CircleCI и Travis по умолчанию запускают сборку только в контейнерах, из популярных CI установленных на своих серверах GitLab CI тоже использует контейнеры. Обычно контейнеры не используются либо там, где этого уровня изоляции недостаточно (и нужна полноценная виртуалка), либо там, где DevOps ещё толком не внедрили, и всё делается по-старинке, как было настроено лет 10 назад.


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

            Тесты пишет много кто, и Вам тоже стоит.


            Если у Вас одноразовый проект-прототип, который пишется для проверки идеи или демонстрации инвесторам, который никто не собирается выставлять в продакшн для реальных юзеров — тогда тесты писать действительно смысла мало, равно как необязательно настраивать CI/CD, и даже tar.gz делать тоже необязательно, проще менять файлы вручную на сервере, как Вам советовали в другом комментарии.


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


            1. kondaurovDev Автор
              10.03.2019 15:02
              -1

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

              Все просто, я предлагаю пушить только сам проект не смешивая его ни с чем, вы отстаиваете что нужно пушить проект только в докер образе. Верно?
              Извините, но меня как-то не очень волнует Ваш личный опыт. Из популярных CI-сервисов и CircleCI и Travis по умолчанию запускают сборку только в контейнерах, из популярных CI установленных на своих серверах GitLab CI тоже использует контейнеры

              Во первых, как работает CI процесс (travis, drone ci, concourse ci), мне без разницы, это никак не касается собранных артефактов и в этой статье вопрос не об этом.
              Тесты пишет много кто, и Вам тоже стоит.

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


              1. powerman
                10.03.2019 15:13

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

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


                как работает CI процесс (travis, drone ci, concourse ci), мне без разницы, это никак не касается собранных артефактов

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


                Ваш CI пайплайн может «забыть» запустить тесты или часть тестов, его пишут люди и частенько коряво

                И что? Это обычно довольно быстро обнаруживается, элементарно исправляется, и, в любом случае, не может являться причиной отказа от написания тестов.


                1. kondaurovDev Автор
                  10.03.2019 15:57

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

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

                  CI может делать сборку изолированно в контейнере и результат работы (артефакты) заливать как tar.gz в репозиторий. В чем проблема?
                  CI нужен, он триггерит события по пушам, это важный этап, я ни в коем случае не говорю что CI не нужен и давайте заливать tar.gz руками. CI это просто «бот» который реагирует на пуши в VCS. Вы настаиваете на том чтобы CI пушил именно докер образы, верно?


                  1. powerman
                    10.03.2019 16:12

                    Нет, я не считаю что сборка любого проекта в CI всегда должна приводить к созданию образа докера.


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


                    Ещё одна причина, хоть и менее важная — упростить запуск. Если в случае одного бинарника юзерам достаточно просто скачать, установить/обновить и запустить его, то в случае tar.gz с проектом на ноде — всё становится несколько сложнее, а докер решает и эту проблему.


                    1. rzerda
                      10.03.2019 16:28

                      Не пойму, о чём вы спорить изволите, Docker image это tar-файлы и есть. Приправленные JSON-ом и с некоторыми соглашениями, но tar-Файлы.


                      1. kondaurovDev Автор
                        10.03.2019 17:02

                        Не пойму, о чём вы спорить изволите, Docker image это tar-файлы и есть. Приправленные JSON-ом и с некоторыми соглашениями, но tar-Файлы.

                        Согласен
                        Ещё одна причина, хоть и менее важная — упростить запуск. Если в случае одного бинарника юзерам достаточно просто скачать, установить/обновить и запустить его, то в случае tar.gz с проектом на ноде — всё становится несколько сложнее, а докер решает и эту проблему

                        таким образом вы заставляете пользователей запускать ваш софт только в докере. если это обычный питон скрипт или стандартное node js приложение, зачем мне нужен докер если у меня стоит последний python иили lts версия node?
                        Зачем оборачивать в докер образ если все и так будет нормально работать без беготни с докером? Почему вы в артефакторий заливаете а не в докер репозиторий? Предлагаете некоторый софт запускать в докере а некоторый чисто на системе потому что он меньше требует окружения?


                        1. powerman
                          10.03.2019 18:12

                          если у меня стоит последний python иили lts версия node?

                          А если не стоят? Нужные версии окружения стоят далеко не у всех, кому нужно запустить проект.


                          Зачем оборачивать в докер образ если все и так будет нормально работать без беготни с докером?

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


                          Понимаете, Ваш вариант включает в себя несколько "если". Если эти "если" выполняются — проект будет работать и без докера. Но вот если они не выполняются… то тут как повезёт… а если не повезёт, то куча времени вылетит на отладку и попытки понять почему не работает. А вариант с докером все эти "если" исключил, заменив их на "да, оно будет нормально работать".


                1. gecube
                  10.03.2019 23:33
                  -1


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

                  И да, и нет.
                  Момент первый. Если внутри идет компиляция (c, c++, golang, rust...) — итоговый бинарник будет каждый раз разный. Повторяемые бинарные сборки есть в роадмапах компиляторов, но такое себе.
                  Второе. Если внутри идет скачивание зависимостей, то как правильно заметили — должен быть lock файл, который гарантирует, что зависимость будет выкачана именно той версии, что и было изначально. Но и этого недостаточно. Нужно, чтобы все зависимые модули были загружены в свое локальное зеркало модулей, иначе есть маленький, но шанс, что кто-то случайно или умышленно нарушит конвенцию и перепушит модуль с измененным кодом, но той же версией (sha-суммой).
                  Третье — контейнер-сборщик то же является предметом для версионирования. Мы пока что используем всегда сборщик с тегом latest. Это в краткосрочной перспективе НЕ ЛОМАЕТ идентичность сборок, но в долгосрочной — сборщик может измениться и старую версию уже не соберешь, но бизнес-ценности именно в сборке старой версии, чтобы она работала у нас и нет.


                  1. powerman
                    11.03.2019 00:11
                    -1

                    Всё верно, но Вы описываете идеальную повторяемость сборки, а я говорил о достаточной на практике:


                    Если внутри идет компиляция (c, c++, golang, rust...) — итоговый бинарник будет каждый раз разный.

                    Необходимости получить абсолютно точно такой же бинарник нет, он вполне может отличаться если в нём, например, сохраняется дата сборки. Главное, чтобы этот бинарник содержал ровно тот же самый код — т.е. чтобы мы смогли получить приложение с тем же поведением.


                    кто-то случайно или умышленно нарушит конвенцию и перепушит модуль с измененным кодом, но той же версией (sha-суммой).

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


                    Мы пока что используем всегда сборщик с тегом latest.

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


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


                    1. gecube
                      11.03.2019 00:20
                      -1

                      Необходимости получить абсолютно точно такой же бинарник нет, он вполне может отличаться если в нём, например, сохраняется дата сборки. Главное, чтобы этот бинарник содержал ровно тот же самый код — т.е. чтобы мы смогли получить приложение с тем же поведением.

                      Вы этого заранее не знаете. В этот раз компилятор разложил переменные в одном порядке, в следующий — в другом. Как правило, этим пренебрегают, т.к. ситуаций, когда это может привести к проблемам ничтожно мало. Но в каких-то corner case — это может взорваться (другая архитектура, сбойная память, баг в другом, но связанном коде и пр.).
                      Более того — понятие, что staing и среда разработчика должны быть копией production, как правило, искажается. 100% идентичности не будет никогда. И задача инженера промоделировать production с допустимой степенью идентичности, которую он же и задает согласно каких-то критериев.
                      Для этих целей текущих возможностей сборки в CI-контейнере вполне достаточно

                      я и не говорю, что CI контейнеры — это зло. Напротив, это очень полезный и удобный инструмент. Но лучше заранее понять его ограничения и особенности.
                      что кто-то сумеет создать архив с модифицированной библиотекой той же версии имеющий ту же SHA-256 (а если кто-то и сумеет, то вряд ли эти усилия оправданы для атаки на повторяемость сборки).

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


      1. gecube
        10.03.2019 23:27

        1. Если вы сделаете docker pull то вы тоже не знаете кто подготовил образ, были ли у него ручные изменения и т.п. Образ может быть вообще битым, если есть права на запись в docker registry то можно запушить хоть hello-world образ под тегом вашего проекта и никто не заметит пока не спулит образ.

        Один из вариантов решения этой проблемы:
        1. разделение на образы, которые временные и могут быть перезаписаны
        2. и образы, которые релизные. Если один раз запушил, то все — его удалить или изменить уже нельзя. Это реализуется либо на уровне registry: docs.docker.com/ee/dtr/user/manage-images/prevent-tags-from-being-overwritten либо на уровне пайплайна (проверяем, что образ есть и не пушим его).


  1. neenik
    10.03.2019 12:04
    +7

    Вы всё переусложнили. Артефакты/репозитории какие-то, это же всё настраивать надо.
    То ли дело — зашёл на сервер, поправил файлик. И пусть тестировщик заходит туда и проверяет.


    1. kondaurovDev Автор
      10.03.2019 12:18
      -1

      А на какой сервер? И какой файлик поправить? :)
      Файлик не поправите без пересборки образа и пуша в docker registry

      Сборка образов и пуши отлично делаются через Ansible. Ничего вручную скачивать не нужно, пишется плейбук который скачивает tar.gz, билдит образ, пушит в docker registry.

      Вообще это что то типа CQRS в программировании. Есть источник который пишет и есть те кто читают


  1. tuxi
    10.03.2019 12:25
    +1

    Сбилдил war, залил на сервер и пошел «кофепить»? :)


    1. kondaurovDev Автор
      10.03.2019 12:29

      Да, с сервером приложений конечно проще :)
      Но это касается только java экосистемы, есть ли похожее для nodejs?
      Все таки докер это унифицированный подход. Как то wildlifly запускал в контейнере и работало))


      1. tuxi
        10.03.2019 12:35

        Да, с сервером приложений конечно проще :)
        В целом да, но тараканов тоже хватает
        есть ли похожее для nodejs?
        Не видел. поэтому я и боюсь этих ваших интернетов докеров :))))
        А какая нить система контроля версия + bash скрипт не выход из положения? Или бинарные данные в большом кол-ве присутствуют?


        1. kondaurovDev Автор
          10.03.2019 12:50

          Все dockerfile, конфигурацию и прочее я храню в git, отдельно от backend и frontend. Раньше я использовал Makefile но сейчас полностью перешел на Ansible. Все билдится и пушится одним прогоном плейбука, Ansible очень крут в этом :)


  1. sved
    10.03.2019 13:27
    -2

    Вся это возня с докерами немного дика для меня.

    Продуктом разработки является приложение + скрипты для миграции данных.
    Основным способом установки приложений являются на виндовс msi, а на Linux rpm/tar.gz
    Собственно самый логичный результат работы CI являются msi/rpm/tar.gz файлы, которые можно запустить самым стандартным установщиком без установки любого постороннего софта.

    Возьмём, к примеру, вариант с rpm.
    Установщик: скопирует файлы и пропишет нужные права, выполнит инсталляционные скрипты после установки и деинсталяционные перед удалением, проверит зависимости и установит необходимые библиотеки (если отсутствуют), проверит версию приложения и архитектуру перед установкой.
    Что ещё надо для обычного приложения?

    Если файлы пушат в репозиторий, то установка/обновление/удаление делается самым простым и примитивным способом, с которым знакомы все системные администраторы.

    Собственно, автор совершенно прав. Я только не согласен с утверждением, что это нигде не используется ибо «в интернете пишут по-другому». Нет, мы именно так и делали, когда разворачивали standalone приложения. Работало идеально


    1. kondaurovDev Автор
      10.03.2019 13:44

      Вы первый кто услышал меня, спасибо))
      То что «в интернете нигде не пишут», я наверное погорячился, она есть конечно но docker way ее просто затемняет и просто не видишь таких практик.
      Докер крут, можно очень просто запустить nginx, базу данных, любой linux с нужным окружением. Но не нужно делать из него серебряную пулю, и не нужно тащить его в CI, не нужно засорять репозитории Dockerfile и инфраструктурными вещами


      1. gecube
        10.03.2019 23:38

        не нужно тащить его в CI, не нужно засорять репозитории Dockerfile и инфраструктурными вещами

        Вы специально путаете теплое с мягким? Не пойму.
        Вот смотрите — есть некий проект. Его артефактом сборки является явно само приложение и его зависимости. Это могут быть как просто бинарные файлы, библиотеки, так и какой-то каталог со скриптами внутри. Далее возникает задача доставить это все на удаленную машину. Понятно, что можно хоть бинарники закидывать на целевой хост, но при этом у нас нет контроля версий. Получается, что нам нужно как-то пакетировать наш артефакт и снабжать метаданными. Класическими способами является загнать это все в пакет для соответствующего пакетного менеджера операционной системы: будь то deb, rpm или что-то еще. Вопрос — должна ли сборка этих артефактов (лучше -) пакетов быть в основном пайплайне? Или отделена от этого? Вопрос ведь не в Dockerfile как таковом (который в самом простом варианте может быть FROM: ubuntu и где-то посередине установка соответствующего deb, полученного на предыдущем шаге).


    1. powerman
      10.03.2019 14:30
      +3

      Не хочется Вас огорчать, но все эти традиционные варианты msi/rpm страдают от той же проблемы — проект устанавливается в неконтролируемом окружении, и из-за этого может не работать либо работать некорректно. Современные технологии развиваются в сторону snap-пакетов, которые намного ближе к контейнерам, чем к msi/rpm.


      1. kondaurovDev Автор
        10.03.2019 15:03

        спасибо за ссылки по Snap!


      1. sved
        10.03.2019 16:46
        +1

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

        Для контроля окружения существуют системы управления конфигурациями.


    1. usego
      10.03.2019 16:08
      +4

      Вот давайте сравним, как быстро вы поставите что-то тяжёлое типа Гитлаба по инструкциям, или развернёте его в виде докера. Я к докерам именно благодаря «отношениям» с гитлабом и пришёл, убив 3 дня на возню с конфигами, плюнув на это и развернув потом тот же Гитлаб из докера за 1 час. Докеризованный софт разворачивать тем же ансиблом многократно легче, так как все вопросы базовой конфигурации уже решены в самом докере руками людей, которые на этом софте и специализируются. Когда ты админ 30 продуктов, разбираться детально в зависимостях каждого — застрелиться можно. А с докером и оркестрацией — без напряга.

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


      1. kondaurovDev Автор
        10.03.2019 16:53

        Вы сейчас говорите вещи которые не связаны с CI и где хранить артефакты. Я тоже запускаю в докере м postgresql, и gitlab поднимал, и mongo, и apache kafka с zookeeper. Все это намного проще развернуть чем устанавливать на голую систему. Но эта статья совершенно не об этом…


        1. usego
          10.03.2019 17:23

          Это ответ на пост выше про возню с докерами как таковую. Про CI я написал выше.


        1. powerman
          10.03.2019 18:15

          Ну вот видите, Вы признаёте, что все эти продукты "намного проще" запускать в докере, а не устанавливать самостоятельно. Так почему же тогда вы не считаете здравым упростить аналогичным образом запуск своего собственного проекта, и хотите чтобы вместо этого юзеры устанавливали его сами из tar.gz?


          1. kondaurovDev Автор
            10.03.2019 18:25

            Ну вот видите, Вы признаёте, что все эти продукты «намного проще» запускать в докере, а не устанавливать самостоятельно. Так почему же тогда вы не считаете здравым упростить аналогичным образом запуск своего собственного проекта, и хотите чтобы вместо этого юзеры устанавливали его сами из tar.gz?

            Это моя первая статья, я не все учел. В следующий раз не буду торопиться опубликовать) У читателей сложилось мнение что я предлагаю отказаться от докера… это совсем не так.
            Я предложил чтобы CI не навязывал докер или подобные вещи.
            Как верно заметил rustler2009 я хочу чтобы CI был отделен от CD. Чтобы CI публиковал только артефакты (бинарники, скрипты, jar'ки и тп), а дальше DevOps занимается доставкой этих артефактов. Они могут упаковать артефакт в любой докер образ, запихнуть в kubernetes, зафигачить в какой нибудь docker swarm.


            1. gecube
              10.03.2019 23:41

              Как верно заметил rustler2009 я хочу чтобы CI был отделен от CD.

              Что есть CI и CD в Вашем понимании? Это очень важно.
              Потому что если речь про CD как развертывание артефакта на удаленные сервера, то действительно возможно отношение один-ко-многим. И, например, держать в основном репозитории описание всех используемых тестовых и production стендов, ну, такое себе. Т.е. получается уже разделение на минимум два репозитория: собственно код проекта и инфраструктурный репозитория, который отвечат ТОЛЬКО за деплой проекта на целевые сервера. Заодно при таком разделении решается куча проблем с правами доступа…


              1. kondaurovDev Автор
                11.03.2019 11:07

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

                CD связан с доставкой артефактов сделанных CI на конечные сервера. Он ничего не знает про GIT, как его собирали из исходников. У него есть просто артефакты, и сервера на которых нужно запустить этот артефакт


                1. gecube
                  11.03.2019 11:16

                  Он ничего не знает про GIT

                  а откуда он (CD) будет брать конфигурацию? Так что Вы лукавите — про git он как раз знает, но немного в другом ключен :-)
                  У него есть просто артефакты, и сервера на которых нужно запустить этот артефакт

                  не обязательно сервера. Это может быть PaaS, например. Или деплоите serverless. Но это так, если придираться к словам.

                  Меня больше беспокоит, что есть «Continuous Delivery» aka CD и «Continuous Deployment» aka CD и их смешивают. Первое — все-таки более общий процесс, наверное.

                  В любом случае, спасибо за ответ. Это дает возможность говорит в единой системе координат.


            1. usego
              11.03.2019 09:34

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


              1. gecube
                11.03.2019 10:53

                Я думаю, что правильно разделить dev-докер-образ (с отладочными функциональностями, софтом latest и прочим, что удобно для разработки, но недопустимо в prod) и QA(UAT)/prod-докер-образ. И два пайплайна. Т.е. QA(UAT) и prod «летят» на одном образе, чтобы снизить ризки.


                1. usego
                  11.03.2019 13:19

                  Мы пока сделали просто — один образ, внутри все конфиги (dev, qa, live) и подключается нужный в зависимости от env variable. Профит — всё под рукой и отслеживаются изменения в конфигах.


            1. ProFfeSsoRr
              11.03.2019 14:43

              а дальше DevOps занимается доставкой этих артефактов

              В идеальном мире DevOps — это практика, которой следуют разработчики. Соответственно фраза меняется на «а дальше этот же программист занимается доставкой». Вот он и занимается как умеет — докером.
              А если посмотреть со стороны отдельного человека (то бишь сис.админа) — так чем меньше свободы и больше унификация — тем лучше. Так что всех загнать в докер и единообразно его использовать для всех приложений проще и выгоднее, чем поддерживать огромную инфраструктуру на все случаи жизни, и с докером, и с пакетами, и просто с tar.gz.


        1. ProFfeSsoRr
          11.03.2019 14:41

          Все это намного проще развернуть чем устанавливать на голую систему.

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


    1. ctacka
      10.03.2019 16:33
      +1

      А если у вас несовместимость внешних библиотек в разных компонентах продукта?


  1. ctacka
    10.03.2019 16:32

    «Конгресс, немцы какие-то. Голова пухнет!»


    1. Как вы версионируете свои тарболы? Ну вот создали вы fix_new_new\ (1).tar.gz, а ваш коллега создал точно такой же, и потер ваш. Через неделю у вас уже полная каша в репозитории, никто не знает какой тарбол уже тестировали, а какой еще нет, какой где установлен, из какого коммита создан какой тарбол.
    2. А еще оказалось, что коллега туда залил конфиги девовские. Ошибся, с кем не бывает. И потом, когда это залили на прод, у вас прод стал ходить к дев базе. Нормально, да?
    3. Через три недели вы решили, что у вас три сайта, и каждый должен ходить к двум другим. Приходит к вам тестировщик, и спрашивает, что ему делать — сайт1 требует библиотеки одной версии, а сайт2 — другой. А еще к нему приходил менеджер и сказал сайт3 взять годовой давности, потому что полгода назад там сделали фикс и поломали совместимость с сайтом2. Что вы ему ответите?


    1. kondaurovDev Автор
      10.03.2019 16:46

      Как вы версионируете свои тарболы? Ну вот создали вы fix_new_new\ (1).tar.gz, а ваш коллега создал точно такой же, и потер ваш. Через неделю у вас уже полная каша в репозитории, никто не знает какой тарбол уже тестировали, а какой еще нет, какой где установлен, из какого коммита создан какой тарбол.

      Точно так же как и docker образы. Коллега не перезатерет тарбол если в репозитории поставить политику «Allow redeploy». А как вы узнаете из какого коммита был создан docker образ интересно?
      А еще оказалось, что коллега туда залил конфиги девовские. Ошибся, с кем не бывает. И потом, когда это залили на прод, у вас прод стал ходить к дев базе. Нормально, да?

      Конфиг можно перезатереть когда делаешь docker образ из тарбола.
      Через три недели вы решили, что у вас три сайта, и каждый должен ходить к двум другим. Приходит к вам тестировщик, и спрашивает, что ему делать — сайт1 требует библиотеки одной версии, а сайт2 — другой. А еще к нему приходил менеджер и сказал сайт3 взять годовой давности, потому что полгода назад там сделали фикс и поломали совместимость с сайтом2. Что вы ему ответите?

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


      1. ctacka
        10.03.2019 17:03

        Точно так же как и docker образы. Коллега не перезатерет тарбол если в репозитории поставить политику «Allow redeploy». А как вы узнаете из какого коммита был создан docker образ интересно?

        Версионированием занимается CI-сервер, он и ставит таги. Базируясь на хэше коммита, например, или на semver. Более того, он может добавлять какие-то переменные или чистить конфиги при создании образа. Он же пишет тестировщику, что и откуда брать для тестирования.


        Конфиг можно перезатереть когда делаешь docker образ из тарбола.

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


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

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


      1. rustler2000
        10.03.2019 17:04

        Ну то есть вместо 'а давайте CI и CD отдекаплим через артифактори' у вас вышло 'давайте избавимся от докера' :))))


        1. kondaurovDev Автор
          10.03.2019 18:43

          Ну то есть вместо 'а давайте CI и CD отдекаплим через артифактори' у вас вышло 'давайте избавимся от докера' :))))

          Похоже что к сожалению так, поторопился с завершением статьи :)
          Версионированием занимается CI-сервер, он и ставит таги. Базируясь на хэше коммита, например, или на semver. Более того, он может добавлять какие-то переменные или чистить конфиги при создании образа. Он же пишет тестировщику, что и откуда брать для тестирования.

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

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

          Я решаю проблему чтобы можно было запустить проект и в докере и просто на сервер где уже есть окружение. Чтобы у DevOps был выбор, как он хочет запустить сервис. Понравится ли вам если вы все будете устанавливать в докер контейнерах?


      1. gecube
        10.03.2019 23:43

        А как вы узнаете из какого коммита был создан docker образ интересно?

        Вариантов два: тегировать изначальный образ sha коммита. Но это плохо, т.к. с одного коммита можно сделать несколько сборок.
        Или более оптимальный вариант именно в ключе докеров — прометить через LABEL сам образ. Записать в него метаданные — из какого репозитория, когда (дата), на каком runner'е, из какого коммита образ был собран.


    1. sved
      10.03.2019 16:55

      Как вы версионируете свои тарболы?

      Это как бы один из базовых функционалов пакетных менеджеров. Версия прописывается при создании rpm. В msi тоже есть версионность. В дебиан пакетах уверен тоже.

      А еще оказалось, что коллега туда залил конфиги девовские.

      Если настройки захардкожены в приложении, то как докер в этом поможет?

      Через три недели вы решили, что у вас три сайта, и каждый должен ходить к двум другим

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


      1. ctacka
        10.03.2019 17:07
        +1

        Это как бы один из базовых функционалов пакетных менеджеров. Версия прописывается при создании rpm. В msi тоже есть версионность. В дебиан пакетах уверен тоже.

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


        Если настройки захардкожены в приложении, то как докер в этом поможет?

        Не докер, а CI-севрер. Топикстартер предлагает отказаться от CI, а не от докера.


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

        Потому что .Net нормально поддерживал множественные версии на одной системе. Попробуйте провернуть то же с glibc.


        1. sved
          10.03.2019 17:23

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


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

          Не докер, а CI-севрер. Топикстартер предлагает отказаться от CI, а не от докера.


          Он вроде не писал что надо отказываться от CI…


          1. ctacka
            10.03.2019 17:35

            Как я понял, он предлагает заменить некоторую цепочку действий CI-сервера ручной загрузкой tar.gz в артифакторий с локальной машины, а потом делать docker из этого архива.
            Мне кажется, тут множество очевидных проблем. Главное — люди усложнают CI не от нечего делать, а для решения определенных проблем. И если у топикстартера нет таких проблем, то это скорее уникальность его проекта, а не какое-то особо правильное видение.


            1. kondaurovDev Автор
              10.03.2019 19:00

              Как я понял, он предлагает заменить некоторую цепочку действий CI-сервера ручной загрузкой tar.gz в артифакторий с локальной машины, а потом делать docker из этого архива.

              CI нужен, это как бот который реагирует на пуши и запускает сборки и заливает артефакт. Он не должен знать про docker…
              Как я понял, он предлагает заменить некоторую цепочку действий CI-сервера ручной загрузкой tar.gz в артифакторий с локальной машины, а потом делать docker из этого архива.

              Да, делать docker образ и добавлять туда артефакт простым скачиванием (не git clone, не компиляция, не прогон юнит тестов). На этапе сборки мне должно быть без разницы как этот артефакт оказался в бинарном репозитории, я просто априори знаю что это протестированный артефакт готовый к работе (иначе его не смогут запушить в репозиторий).
              Этот артефакт могут пушить как разработчики так и наш CI который по коммитам сам будет собирать и заливать артефакт…


              1. ctacka
                10.03.2019 19:37

                А, ну мне кажется я вас начал понимать. Вы хотите быть генерировать platform-agnostic артефакт.
                Это вполне обычное дело, мы "собираем" код и запускаем тесты, и после этого мы можем полученный пакет выложить как некий промежуточный артефакт, zip-ом или тарболом. И уже при деплойменте паковать его для той платформы, в которую деплоим: докер, лямбда, что угодно.
                Я правильно понимаю?


                1. kondaurovDev Автор
                  10.03.2019 20:19

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


                  1. gecube
                    10.03.2019 23:46

                    Их можно смело брать упраковывать в любую технологию, все должно работать

                    Полностью поддерживаю. Т.е. мы просто докер подразумеваем как такой же способ дистрибуции (пакетирования) приложения как rpm/deb/msi/tar.gz/бинарь/любой другой вариант


  1. roller
    10.03.2019 17:12
    +1

    Докер создан в первую очередь для удобного _удаления_ установленного софта! Не надо нигде сохранять зависимости, искать хвосты и мусор по всей системе. Дропнул контейнер и/или его волюмы — и все!
    Шутка. А может и нет.


  1. vpiskunov
    10.03.2019 17:40
    +1

    Эта статья напоминает ситуацию, когда начинает только внедряться CI/CD на околоконтейнерный (и Kubernetes) историях, что очень вычищает серверы, кодовую базу пайплайном и очень упрощает различные прлцедуры верификации (от юнит до e2e на большом парке микроскрвисов). При этом разработчики еще не вкурили что и как или лень переучиваться и начинают предлагать костыли.


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


  1. alexesDev
    10.03.2019 21:24
    +1

    А ничего, что docker image это такой же tar.gz, только с бинарником ноды?


  1. Softer
    10.03.2019 21:58
    +1

    Я, конечно, противник «внедрения докера во все дыры», но при чем тут вообще докер? У CI/CD ведь задача «доставить и развернуть». Хоть банальный git pull, хоть запуск миграций. Не обязательно же в докер.

    ЗЫ: Но есть 1 плюс докера все же — везде у приложения единое окружение.


  1. gecube
    10.03.2019 22:18
    -1

    Каким-нибудь образом на удаленном сервере делается git pull (chef, puppet, вручную через docker-compose) и запускается контейнер.

    Какой ещё гит пулл на удаленном сервере? Дальше можно не читать. Это не продакшн решения. Как минимум, автор не очень-то слышал про scm (ansible, salt, chef, puppet).


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

    Вывод, кстати, верный. Есть кейсы, где нужны отдельные хранилища артефактов. Например, для тех же pip-модулей, node js модулей, библиотек golang. В некоторых случаях их можно забирать из git репозитория, в некоторых — удобно хранить как бинарные блобы.
    Касательно докера — это только один из способов дистрибуции ПО. Помимо этого есть возможность распространять как бинарники (примеры: prometheus, docker-compose, traefik etc). Так и нативные бинарные пакеты для различных дистрибутивов и операционных систем. Но это более характерно для ПО для массового рынка. Если же у Вас разработка своя и существующая только внутри периметра (и предоставляется клиентам, например, по модели SaaS), то пакетирование в докеры (или любой другой совместимый тип образов) может оказаться единственно оправданным вариантом артефакта


    1. kondaurovDev Автор
      10.03.2019 22:57

      Как минимум, автор не очень-то слышал про scm (ansible, salt, chef, puppet).

      Я опечатался, нужно было написать docker pull. Использую ansible, был опыт работы с Chef и его кукбуками с рецептами. Infrastructure as code мне знакомо


      1. gecube
        10.03.2019 23:20
        -1

        Я опечатался, нужно было написать docker pull.

        Ну, тогда могу пожелать в следующий раз вычитывать статью внимательнее и не торопиться ) Прошу тогда соответственно поправить статью, чтобы не было недопонимания. Принято, в общем.
        Использую ansible, был опыт работы с Chef и его кукбуками с рецептами. Infrastructure as code мне знакомо

        ОК. Принято. Расскажите, пожалуйста — и как — ansible для деплоя используете? Как впечатления? Какие типовые задачи решаете?


        1. kondaurovDev Автор
          11.03.2019 10:49

          Я хочу написать отдельную статью про использования ансибла, как доставляю артефакты и запускаю сервисы) Впечатления отличные, вопрос только в понимаи как пишутся плейбуки, как делать reusable блоки чтобы не было копипаста. Из задач сейчас: сборка докер образов на машине где будет запускаться докер контейнер, запуск инфраструктуры типа бд, nginx, nexus.


          1. gecube
            11.03.2019 10:50

            Очень ждем.


          1. Framework
            11.03.2019 14:54

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

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

            Если не делать 'FROM: ubuntu:latest', а открыть для себя alpine образы, то в итоге образ и будет тем самым артефактом в котором нет ничего кроме приложения с минимально необходимыми для него зависимостями. Да, так нельзя запустить наше приложение на машине без докера, но фокус в том, что вне докера у приложения есть другие зависимости от самых разных библиотек и их установка может быть в разы сложнее установки докера. А если вдруг мы писали на маке, тестировщик тестит на винде, а на проде линукс, то…

            Позже открыл для себя системы оркестрации (сначала Docker Swarm, сейчас Kubernetes) и managed databases, выбросил ansible. Конфигов стало меньше, реюзабельность стала выше (в CI/CD для Python и Go, например, отличается один только Dockerfile).


  1. Yeah
    11.03.2019 01:23
    +1

    Задумайтесь: зачем мы тащим весь этот Docker раньше времени? Потому что считается, что в контейнере удобно и “Ну нормально же все было, работает. Чего ты начинаешь то?”.
    Так вот, для таких людей я могу сказать — докер контейнеры это не панацея и не единственная среда, в которой может исполняться ваше приложение.

    У нас случай был. Написали код, все тесты прошли, все хорошо. Закинули в CircleCI, а тесты там запускались в докере — и они упали. Начали разбираться и выяснили, что у разработчика и в докере установлены разные часовые пояса, а код это дело не учитывает. А так как прод работает на докере, то это была проблема, которую бы не заметили, если бы не прогон тестов в среде идентичной проду. Так что теперь у нас npm run docker:test стоит на prepush — во избежание


  1. devian3000
    11.03.2019 10:50
    +1

    Эм, какой-то бред…
    В зависимости от приложения выбираешь метод распространения.
    Хочется разделить CI и CD кидайте хук по завершению CI зачем куда-то в архив писать?

    Серверные приложения намного удобнее распространять через docker или vagrant или другие способы изоляции (как раз сохранение окружения). И всегда всё будет работать именно так как должно.
    Сборки десктопа или т.д. так же вешаем два или более паплайнов и собираем хоть rpm хоть deb хоть msi, хоть всё вместе разом. И мы точно знаем какие там зависимости, и что это будет работать.
    Приложение не отделимо от окружения, а окружение от работоспособности софта, скидывать бинарник который чёрт знает от чего зависит, или сорцы которые чёрт знает как собирать, просто быть самому себе злым буратино.


    1. kondaurovDev Автор
      11.03.2019 10:58

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

      Нет, процесс как раз один и тот же, результат в tar.
      по завершению CI зачем куда-то в архив писать?

      Чтобы можно было потом запустить его либо на чистой системе, либо промежуточным этапом собрать докер образ с нужным окружением и запихнуть туда tar
      Серверные приложения намного удобнее распространять через docker или vagrant или другие способы изоляции (как раз сохранение окружения)

      БД это тоже серверное приложение, однако, позвольте спросить, она только в докере распространяется?
      Postgresql можно запустить на чистом метале или… упаковать в докер образ
      Приложение не отделимо от окружения, а окружение от работоспособности софта, скидывать бинарник который чёрт знает от чего зависит, или сорцы которые чёрт знает как собирать, просто быть самому себе злым буратино.

      1. Сорцы в tar не будут, там готовые оттесченые артефакты
      2. тарболы можно также организовать как и докер образы.
      3. политику кто может загружать тарболл, ее можно настроить также как и в докер репозитории (если не лучше)


      1. devian3000
        11.03.2019 13:29

        Нет, процесс как раз один и тот же, результат в tar.


        Зачем? какая версия для интерпретируемых языков? Какая виртуальная машина для Java и C# где вся эта информация будет храниться? Как легко и просто всё это установить?

        Чтобы можно было потом запустить его либо на чистой системе, либо промежуточным этапом собрать докер образ с нужным окружением и запихнуть туда tar

        Тот же самый вопрос, какие зависимости? Библиотеки? Конфиги? Куда всю эту инфу нужно класть?

        БД это тоже серверное приложение, однако, позвольте спросить, она только в докере распространяется?
        Postgresql можно запустить на чистом метале или… упаковать в докер образ

        Можно конечно, но зачем? У вас нет полной изоляции от системы, образ окружения может пользоваться всеми вычислительными способностями машины, конфиги можно пробросить. И Postgres поставляется в пакете deb или rpm на машины, или собирается также через makefile с установкой всего куда нужно. Опять же, makefile по сути тот же Dockerfile или Vagrant file. Что мешает собирать 3-4-5-25 вариантов и в докер и в deb и в tar сорцы запихивать.

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