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

Стадии

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

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

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

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

Сигнатура стадии используется для тегирования стадии в хранилище стадий. werf не собирает стадию, если стадия с такой сигнатурой уже находится в хранилище стадий (это поведение похоже на кэширование в Docker, только имеет более сложную логику).

Сигнатура стадии — это контрольная сумма от:

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

Зависимости стадии

Зависимости стадии — это данные, которые напрямую связаны и влияют на сигнатуру стадии. К зависимостям стадии относятся:

  • файлы (и их содержимое) из git-репозиториев;
  • инструкции сборки стадии из файла werf.yaml;
  • произвольные строки указанные пользователем в werf.yaml
  • и т.п.

Большинство зависимостей стадии определяется в файле конфигурации werf.yaml, остальные — во время запуска.

Следующая таблица иллюстрирует зависимости в Dockerfile-образе, Stapel-образе и Stapel-артефакте. Каждая строка таблицы описывает зависимости для определенной стадии. Левая колонка содержит краткое описание зависимостей, правая содержит соответствующую часть werf.yaml и ссылки на разделы с более подробной информацией.

stage dockerfile

target dockerfile instructions
hashsum of files related with ADD and COPY dockerfile instructions
args used in target dockerfile instructions
addHost
image: <image name... || ~>
dockerfile: <relative path>
context: <relative path>
target: <docker stage name>
args:
  <build arg name>: <value>
addHost:
- <host:ip>

stage from

from
or from image id
or from artifact id
actual digest from registry (if fromLatest: true)
fromCacheVersion
mounts
from: <image[:<tag>]>
fromLatest: <bool>
fromCacheVersion: <arbitrary string>
fromImage: <image name>
fromImageArtifact: <artifact name>
mount:
- from: build_dir
  to: <absolute or relative path>
- from: tmp_dir
  to: <absolute path>
- fromPath: <absolute or relative path>
  to: <absolute path>

stage beforeInstall

beforeInstall bash commands or ansible tasks
cacheVersion
beforeInstallCacheVersion
shell:
  beforeInstall:
  - <bash command>
  cacheVersion: <arbitrary string>
  beforeInstallCacheVersion: <arbitrary string>

or

ansible:
  beforeInstall:
  - <task>
  cacheVersion: <arbitrary string>
  beforeInstallCacheVersion: <arbitrary string>

stage importsBeforeInstall

imports before install
import:
- artifact: <artifact name>
  before: install
  add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>

stage gitArchive

git mappings
git:
- add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>
- url: <git repo url>
  branch: <branch name>
  commit: <commit>
  tag: <tag>
  add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>

stage install

install bash commands or ansible tasks
installCacheVersion
git files hashsum by install stageDependency
git:
- stageDependencies:
    install:
    - <relative path or glob>

shell:
  install:
  - <bash command>
  installCacheVersion: <arbitrary string>

or

ansible:
  install:
  - <task>
  installCacheVersion: <arbitrary string>

stage importsAfterInstall

imports after install
import:
- artifact: <artifact name>
  after: install
  add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>

stage beforeSetup

beforeSetup bash commands or ansible tasks
beforeSetupCacheVersion
git files hashsum by beforeSetup stageDependency
git:
- stageDependencies:
    beforeSetup:
    - <relative path or glob>

shell:
  beforeSetup:
  - <bash command>
  beforeSetupCacheVersion: <arbitrary string>

or

ansible:
  beforeSetup:
  - <task>
  beforeSetupCacheVersion: <arbitrary string>

stage importsBeforeSetup

imports before setup
import:
- artifact: <artifact name>
  before: setup
  add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>

stage setup

setup bash commands or ansible tasks
setupCacheVersion
git files hashsum by setup stageDependency
git:
- stageDependencies:
    setup:
    - <relative path or glob>

shell:
  setup:
  - <bash command>
  setupCacheVersion: <arbitrary string>

or

ansible:
  setup:
  - <task>
  setupCacheVersion: <arbitrary string>

stage gitCache

size of git diff between last used commit and actual

stage importsAfterSetup

imports after setup
import:
- artifact: <artifact name>
  after: setup
  add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>

stage gitLatestPatch

presence of git diff changes between last used commit and actual

stage dockerInstructions

docker instructions
docker:
  VOLUME:
  - <volume>
  EXPOSE:
  - <expose>
  ENV:
    <env name>: <env value>
  LABEL:
    <label name>: <label value>
  ENTRYPOINT: <entrypoint>
  CMD: <cmd>
  WORKDIR: <workdir>
  USER: <user>
  HEALTHCHECK: <healthcheck>

Хранилище стадий

Хранилище стадий содержит стадии проекта. Стадии могут храниться локально на хост-машине, либо в Docker registry.

Большинство команд werf используют стадии. Такие команды требуют указания места размещения хранилища стадий с помощью ключа --stages-storage или переменной окружения option or WERF_STAGES_STORAGE. На текущий момент поддерживается только локальное размещение хранилища стадий — ключ :local.

Именование стадий

Стадии в хранилище стадий именуются согласно следующей схемы: werf-stages-storage/PROJECT_NAME:STAGE_SIGNATURE ,где:

  • PROJECT_NAME — имя проекта
  • STAGE_SIGNATURE — сигнатура стадии

Образы

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

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

werf создает образы используя хранилище стадий. На текущий момент, образы создаются только в процессе публикации (publish) и хранятся в репозитории образов.

Конфигурация образов должна быть описана в файле конфигурации werf.yaml.

Читай подробнее о процессе сборки.