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

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

RUN “download-source && cmd && cmd2 && remove-source”

Но при таком использовании не получится использовать кэширование, а это время на постоянную установку инструментария.

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

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

dimg do
  docker.from 'ubuntu:16.04'

  # определение приложения артефакта
  artifact do
    # добавление исходных файлов и зависимости пересборки артефакта от любого изменения
    git.add do
      to('/app')
      stage_dependencies.build_artifact('*')
    end

    shell do
      # установка инструментов сборки
      install.run('apt-get install build-essentials libmysql-dev')
      # сборка
      build_artifact.run('make -C /app')
    end

    # определение артефакта, импортирование `/app/build` в `/usr/bin` приложения после стадии `setup`
    export('/app/build') do
      to('/usr/bin/app')
      after('setup')
    end
  end
end

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

Разница между стадиями заключается в следующем:

  • на стадии build_artifact определяются шаги для сборки артефакта, зависимости от файлов которой можно описать в stage_dependencies в директиве git;
  • за наложение финального патча отвечает стадия g_a_artifact_patch, которая будет собрана только в том случае, если потребуется пересобрать build_artifact;
  • не используется стадия docker_instruction, так как приложение артефакта является служебным.

При отсутствии зависимостей у стадии build_artifact артефакт закэшируется после первой сборки и не будет пересобираться.

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

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

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