Окружение для разработки и CI

Я стараюсь автоматизировать все задачи проекта и использовать для локальной разработки и CI один и тот же набор решений. Не только то, что касается test/build/deploy, но и все остальные повторяющиеся задачи, типа инициализации окружения разработчика, подготовки данных, генерации документации и так далее. Это дает независимость от текущей реализации CI, отсутствие дублирования функций, постоянный догфудинг разработчиками и стимулирует команды сомостоятельно управлять и развивать CI своего продукта. У такого решения есть и очевидная обратная сторона - приходится в рамках одного решения удовлетворить все требования для обоих миров. Чаще всего от этого страдает скорость сборки, читаемость результатов и простота.

Основные требования:

  • Изоляция: Запуск всех инструментов в Docker-контейнерах
  • Скриптинг: Поддержка современных языков (TS/Go/Py) вместо чистого bash/YAML
  • Open Source: Без привязки к SaaS, возможность форка
  • Языковая агностичность: Один фреймворк независимо от стека проекта
  • Seamless CI: Запуск тех же скриптов локально и в CI
  • Кэшируемость: BuildKit-кеш, remote-cache, Depot?, параллелизм
  • Безопасность: rootless-user, secrets-mounts
  • Мультиплатформенность: arm64/amd64, macOS + Linux (OrbStack/WSL-2)
  • Низкий порог входа: минимум концепций и необходимых команд

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

ТребованиеНасколько подходит Dagger
Изоляция✅ Все этапы выполняются в контейнерах через BuildKit
Низкий порог входа⚠️ CLI простая, но нужны новые абстракции (Graph, функции)
Скриптинг (TS/Go/Py)✅ Поддержка Go, Python, TypeScript SDK
Open Source✅ Движок и SDK MIT-лицензия, можно форкнуть
Языковая агностичность✅ Контейнеризированный подход не зависит от стека приложения
Seamless CI✅ Один и тот же код работает локально и в большинстве CI (Docker-in-Docker или sibling)
Кэшируемость✅ BuildKit-кеш и автоматическое кеширование функций; ⚠️ Remote-cache требует Dagger Cloud
Безопасность⚠️ Есть rootless-mode и secrets-mounts, но сканирование образов придётся подключать вручную
Мультиплатформенность✅ Работает на macOS (arm64/amd64) и Linux; Windows пока в бете

Плюсы

  • Единый код для CI и локальной разработки — «no more push & pray».
  • Программируемость: полноценные языки вместо YAML позволяют делать условия, циклы, переиспользуемые функции.
  • Кэширование и параллелизм из коробки благодаря BuildKit.
  • Модульность: Daggerverse и собственные модули упрощают переиспользование пайплайнов.
  • Хорошая DX: интерактивное выполнение dagger run, встроенная трассировка.

Минусы

  • Кривая обучения: нужно понять модель графа и принципы BuildKit.
  • Молодой проект: API ещё может меняться, меньше примеров, чем у GitHub Actions.
  • Зависимость от Docker: без контейнерного демона не запустится (OrbStack/Colima/WSL-2).
  • Windows: официальная поддержка в бета-стадии.

Подводные камни и рекомендации

  1. Remote Cache = Dagger Cloud. Для полноценного удалённого кеша нужен SaaS-аккаунт; offline-режим только локальный кеш.
  2. Secrets. Нужна отдельная логика для передачи секретов (env/secrets API), иначе случайно попадут в логи.
  3. Перфоманс на macOS ARM. BuildKit в контейнере может работать медленнее из-за эмуляции x86, осторожно с multi-arch.
  4. Доставка артефактов. Сам Dagger не пушит в реестры/сториджи — нужно явно описывать шаги или подключать модули.
  5. Отладка. При ошибках иногда помогает dagger session с включённым --debug, иначе стек вызовов неочевиден.

В итоге Dagger хорошо закрывает большинство моих требований и выглядит перспективно как единый инструмент для dev-env и CI. Критические риски — молодость экосистемы и зависимость от Dagger Cloud для удалённого кеша. Если команда готова инвестировать время в освоение новых концепций и устраивает текущий уровень стабильности, Dagger может стать основой будущей инфраструктуры.