Шпаргалка: werf

Полный разбор — M3, M8, капстоун M11.

Самые используемые команды

1
2
3
4
5
6
7
8
werf build [<image-name>]                    # сборка одного или всех образов
werf converge --repo <registry> [--env <env>]   # build + publish + deploy (Nelm) одной командой
werf render                                    # отрендерить манифесты без применения
werf run <image> -- <command>                  # запустить команду в собранном образе (проверка содержимого)
werf cleanup --repo <registry>                 # удалить неиспользуемые образы по keepPolicies
werf bundle publish --repo <registry> --tag <tag>
werf bundle apply --repo <registry> --env <env> --tag <tag>
werf build --repo <registry> --cache-repo <cache-registry>   # ускорение сборки в CI через отдельный кэш

CLI: сборка

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
werf build                                    # собрать все image:-блоки из werf.yaml
werf build <image-name>                        # собрать один образ (+ все его dependencies)
werf build --repo <primary-registry>           # собрать и опубликовать в registry
werf build --repo <repo> --cache-repo <cache>  # публиковать кэш слоёв в отдельный OCI cache-repo
werf build --repo <repo> --cache-repo <c1> --cache-repo <c2>  # несколько cache-repo (повторить флаг)
werf build --repo <repo> --add-custom-tag "%image%-latest"    # человекочитаемый алиас поверх content-based тега
werf build --repo <repo> --add-custom-tag "v1.2.3" --add-custom-tag "%image%-latest"  # несколько тегов сразу
werf build --check-built-images                # проверить, что все образы уже собраны и есть в repo (без сборки, ошибка если нет)
werf config render                             # отрендерить итоговый werf.yaml после Go-шаблонов (валидация)
werf config render --require-built-images .    # рендер с учётом dependencies/imports уже собранных образов
werf config list                               # список всех image:-блоков конфигурации
werf config graph                              # граф зависимостей образов (dependsOn/import) без сборки

--dry-run у werf build не существует (есть у werf run/werf cleanup/werf host cleanup). --require-built-images — флаг werf render/werf converge, а не werf build (см. секцию «CLI: деплой» ниже).

Плейсхолдеры --add-custom-tag/--tag:

1
2
3
4
%image%              # имя образа из werf.yaml (нужно при нескольких image:-блоках)
%image_slug%          # slug-версия имени образа
%image_safe_slug%     # безопасный для DNS/registry slug имени
%image_content_based_tag%   # реальный content-based тег (детерминированный хэш содержимого)

CLI: запуск и экспорт

1
2
3
werf run <image> -- <command>                  # запустить контейнер из собранного образа
werf run <image> -- sh -c "<command>"           # составная команда внутри контейнера
werf export --repo <repo> --tag <repo>/<name>:%image_content_based_tag%   # экспорт с content-based тегом для внешних систем

CLI: деплой

1
2
3
4
5
6
7
werf render                                    # отрендерить манифесты (без apply)
werf render --require-built-images --output manifests.yaml --repo <repo>  # рендер после публикации образов
werf converge --repo <repo> [--env <env>]      # build + publish + deploy одной командой
werf converge --require-built-images --repo <repo> [--env <env>]  # деплой без пересборки (после отдельного werf build)
werf plan                                      # предпросмотр изменений перед converge (аналог nelm release plan)
werf dismiss                                   # снять релиз с кластера (обратное converge)
werf deploy                                    # деплой-часть, обычно вызывается внутри converge

CLI: bundle (публикация чарта как OCI-артефакта)

1
2
3
4
5
6
werf bundle publish --repo <bundle-repo>                       # собрать образы + опубликовать чарт как OCI-бандл
werf bundle publish --repo <bundle-repo> --tag <version>       # публикация с явной версией
werf bundle apply --repo <repo> --env <env> --tag <version>    # развернуть ранее опубликованный бандл без доступа к git
werf bundle apply --repo ghcr.io/group/project --env production --tag 1.0.0
werf bundle render --output manifests.yaml --tag <tag> --release <name> --namespace <ns> --repo <repo>  # рендер из бандла без git
werf mirror                                                     # зеркалирование бандла в air-gapped контур

CLI: cleanup registry

1
2
3
4
werf cleanup --repo <registry>                  # очистка по политикам keepPolicies из werf.yaml
werf cleanup --dry-run --repo <registry>        # предпросмотр очистки без удаления
werf cleanup --repo <registry> --keep-list=<file>  # явный список образов для сохранения
werf host cleanup                                # локальная очистка кэша/данных werf на хосте (для CI-раннеров)

Environment variables

1
2
export WERF_CACHE_REPO_1=<cache1>               # первый cache-repo вместо флага --cache-repo
export WERF_CACHE_REPO_2=<cache2>               # второй cache-repo

werf.yaml — метаданные проекта

1
2
project: <name> # имя werf-проекта
configVersion: 1 # версия схемы конфигурации werf.yaml

werf.yaml — Dockerfile-builder

1
2
3
4
5
6
image: <name> # объявление образа (мультидокумент через ---)
dockerfile: <path> # путь к Dockerfile
context: <path> # build context (поддиректория монорепозитория)
target: <stage> # выбор стадии multi-stage Dockerfile (аналог docker build --target)
args:
  <BUILD_ARG>: "{{ .Version }}" # build-аргументы с Go-шаблонами werf

werf.yaml — Stapel-builder

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from: <image>                 # базовый образ Stapel-builder
git:
  - add: /<path>                # добавить файлы из Git-репозитория в образ
    to: /<path>                  # маппинг Git-пути в путь внутри образа
  stageDependencies:
    install: ["<mask>"]           # инвалидация стадии install по маскам файлов
    beforeSetup: ["<mask>"]
    setup: ["**/*.go"]
shell:
  beforeInstall: ["<commands>"]  # системные пакеты, редко меняющиеся (apt/apk)
  install: ["<commands>"]        # установка зависимостей приложения (npm/bundle/go mod)
  beforeSetup: ["<commands>"]    # конфигурация системы, сборка ассетов
  setup: ["<commands>"]          # финальная сборка/генерация конфигурации
ansible:                          # альтернатива shell: — декларативные Ansible-задачи (взаимоисключающе с shell:)
  install:
    - apt: { name: <pkg>, state: present, update_cache: true }
cacheVersion: "<value>"            # принудительный сброс кэша ВСЕХ стадий образа
installCacheVersion: "v2"           # сброс кэша конкретной стадии (<stage>CacheVersion)

Стадии Stapel (beforeInstallinstallbeforeSetupsetup) — порядок важен для инвалидации кэша: реже меняющиеся стадии ставьте раньше.

werf.yaml — линковка образов (dependencies/imports)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
dependencies:
  - image: <name> # зависимость от другого image:-блока
    imports:
      - type: ImageName # полное имя образа (без тега) как build-arg
        targetBuildArg: <ARG>
      - type: ImageTag # только тег образа
        targetBuildArg: <ARG>
      - type: ImageRepo # путь к репозиторию без тега
        targetBuildArg: <ARG>
      - type: ImageDigest # content-based дайджест (детерминированная адресация)
        targetBuildArg: <ARG>

В Dockerfile каждый targetBuildArg нужно явно объявить через ARG <ARG_NAME> — werf не делает это автоматически.

werf.yaml — Stapel import (копирование файлов между образами)

1
2
3
4
5
6
7
8
9
import:
  - image: <source-image> # свой image:-блок ЛИБО произвольный внешний образ (name:tag / name@digest)
    add: <path>
    to: <path>
    after: <stage> # или before: <stage>  — install|setup, ТОЛЬКО для целевого Stapel-образа
    includePaths: ["<mask>"]
    excludePaths: ["<mask>"]
    owner: <user>
    group: <group>

Целевой (принимающий import) образ обязан быть Stapel — after/before завязаны на его стадиях. Источником при этом может быть как Stapel/Dockerfile-образ этого же werf.yaml, так и произвольный внешний образ (node:24-alpine), нигде не объявленный в конфигурации.

werf.yaml — build-time секреты (giterminism)

1
2
3
4
5
6
7
secrets:
  - env: <VAR_NAME> # секрет из переменной окружения (id = имя переменной)
  - id: <id>
    env: <VAR_NAME> # секрет из env с явным id для /run/secrets/<id>
  - src: <path> # секрет из локального файла (например ~/.aws/credentials)
  - id: <id>
    value: <string> # секрет со значением прямо в werf.yaml (обычно через шаблон)

Чтение секрета внутри shell:/Dockerfile RUN --mount=type=secret:

1
2
$(cat /run/secrets/<id>)
export NPM_TOKEN="$(cat /run/secrets/npm_token)"

werf-giterminism.yaml

1
2
3
4
5
6
giterminismConfigVersion: 1
config:
  secrets:
    allowEnvVariables: ["<VAR>"] # явное разрешение env-переменных как build-time секретов
    allowFiles: ["<path>"] # явное разрешение локальных файлов как секретов
    allowValueIds: ["<id>"] # явное разрешение секретов с value:

werf.yaml — cleanup registry (keepPolicies)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
cleanup:
  keepPolicies:
    - references:
        tag: /^v\d+\.\d+\.\d+$/ # regex по git-тегам (без префикса origin/)
        branch: /<regex>/ # regex по git-веткам
        limit:
          last: <N> # хранить последние N подходящих ссылок
          in: <duration> # ограничить поиск периодом (например 168h = 7 дней)
          operator: And # And — оба условия limit; Or — достаточно одного
      imagesPerReference:
        last: <N> # хранить последние N версий образов на ссылку (дефолт 1)
        in: <duration>
        operator: Or

Дополнительно: обзор командных групп werf (официальная документация)

1
2
3
4
5
Delivery:  werf converge, werf rollback, werf plan, werf dismiss, werf bundle
Cleaning:  werf cleanup, werf purge, werf host cleanup
Helpers:   werf ci-env, werf build, werf export, werf run, werf kube-run,
           werf compose, werf slugify, werf render, werf lint, werf chart,
           werf includes, werf stages

werf ci-env автоматически прокидывает переменные CI (например CI_REGISTRY_IMAGE) в конфигурацию --repo/тегирования — полезно вместо ручного экспорта в .gitlab-ci.yml.