How's that again?

dapp

Сейчас умеет только собирать образ и складывать в Docker Registry

Будет поддержка полного цикла CI/CD

Требования к подобной системе

  • образы должны собираться меньше чем за 10 секунд
  • размер образов должен быть меньше 200 МБ
  • коммит на 10 КБ должен увеличивать образ на 10 КБ, а не на 400 МБ

Проблемы и решения

Стейджи

В dapp выделили несколько стейджей в процессе сборки:

  • before_install
  • install
  • before_setup
  • setup

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

Внешний контекст

Если мы одним из шагов в Dockerfile делаем RUN apt-get update, то размер образа сильно вырастает.

Мы можем сделать так:

RUN apt-get update && apt-get install -y netcat && rm -rf /var/lib/apt

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

Решение: маунтить папку /var/lib/apt с хоста. Первое построение образа ее заполнит, остальные будут переиспользовать. Если воркеров несколько, то эту папку можно положить на отдельный сервак и пошарить через NFS.

Можно использовать этот паттерн, например, для:

  • apt, yum
  • bundler, pip, composer, npm, bower
  • ccache, кэш "сборщика ассетов"

git

Добавлять все исходники каждый раз в проект - долго.

Непонятно, какие стадии пересобирать при добавлении каких файлов.

Непонятно, как проставлять владельца и права.

Решение: в dapp сделали специальный стейдж git archive - это выкачивание исходников из репозиторий на момент первой сборки. Этот стейдж идет вторым этапом, между before_install и install. А последний шаг - git patch apply.

В результате каждый следующий коммит это добавление дельты между архивом и текущим состоянием.

При этом в dapp мы можем указать, что изменения в каком-либо файле должны приводить к пересборке какого-либо из более ранних стейджей. Например, изменения в packages.json должны приводить к пересборке install.

Когда размер дельты между архивом и текущим состоянием достигает 1 МБ - этот патч фиксируется в образе в виде слоя и следующие патчи пойдут уже поверх этого слоя. Когда достигается лимит на количество слоев в образе - пересобирается архив.

Артефакты

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

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

Chef

Там еще какая-то поддержка модулей shell через использование Chef, но я в этом не разбираюсь.