Окружение для разработки и 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: официальная поддержка в бета-стадии.
Подводные камни и рекомендации
- Remote Cache = Dagger Cloud. Для полноценного удалённого кеша нужен SaaS-аккаунт; offline-режим только локальный кеш.
- Secrets. Нужна отдельная логика для передачи секретов (env/secrets API), иначе случайно попадут в логи.
- Перфоманс на macOS ARM. BuildKit в контейнере может работать медленнее из-за эмуляции x86, осторожно с multi-arch.
- Доставка артефактов. Сам Dagger не пушит в реестры/сториджи — нужно явно описывать шаги или подключать модули.
- Отладка. При ошибках иногда помогает
dagger sessionс включённым--debug, иначе стек вызовов неочевиден.
В итоге Dagger хорошо закрывает большинство моих требований и выглядит перспективно как единый инструмент для dev-env и CI. Критические риски — молодость экосистемы и зависимость от Dagger Cloud для удалённого кеша. Если команда готова инвестировать время в освоение новых концепций и устраивает текущий уровень стабильности, Dagger может стать основой будущей инфраструктуры.