ADR 0170 — Dev-compose становится brabo-dev, и dev отказывается подниматься рядом с установкой
Статус
Accepted. Решение сопровождающего от 2026-09-27 (AT-173): "оба" — собственное
имя для dev И защита. Ссылается на ADR 0150
(compose установки, который родился, утверждая, что у него name, отличный от dev) и
ADR 0152 (важные тома).
Не редактирует ни один из них.
Контекст
Измерено 2026-09-19: docker/docker-compose.yml (dev) и
docker/docker-compose.install.yml оба объявляли name: brabo.
Комментарий compose установки утверждал обратное — "name diferente
do compose de dev de propósito: os dois podem coexistir na mesma máquina" — и
это было неправдой. Для Docker машина с установкой И checkout имела ОДИН
проект: контейнеры (brabo-api-1, brabo-postgres-1…), сеть
(brabo_default) и тома с одинаковыми именами (brabo_pgdata,
brabo_neo4j_data, brabo_git_local_repos, brabo_project_workspaces…) были
одними и теми же.
Три последствия, первое измерено:
- подъём одного compose поверх другого ПЕРЕСОЗДАЁТ контейнеры другого и подключает их к его базе — база установки получила миграцию из dev;
scripts/dev/reset-total.shделаетDROP SCHEMA … CASCADEв Postgres проектаbrabo— то есть стёр бы базу установки;docker compose downодного роняет другой.
Продакшен-compose (docker-compose.prod.yml) уже был brabo-prod и сюда
не входит.
Решение
1. Dev-compose начинает называться brabo-dev. Контейнеры
brabo-dev-<serviço>-1, сеть brabo-dev_default, тома brabo-dev_<chave>.
Overlay наблюдаемости (docker-compose.observability.yml) повторяет
имя, потому что name: ПОСЛЕДНЕГО -f побеждает, и другое значение там перенесло бы
весь стек в другой проект; его Alloy фильтрует по
com.docker.compose.project=brabo-dev.
Compose установки ОСТАЁТСЯ brabo. Это имя, которое уже есть у сделанных установок, и
его смена отключила бы каждую от собственных томов при следующем обновлении —
цена легла бы на того, кто никогда не читал этот репозиторий. Меняется сторона того,
кто разрабатывает, кто читает CHANGELOG и имеет runbook.
2. Защита в preflight.mjs и reset-total.sh. Оба ОТКАЗЫВАЮТ,
называя найденные контейнеры и down (без -v) каждого файла, когда
на машине есть контейнер — в любом состоянии, docker ps -a, — чья метка
com.docker.compose.project.config_files указывает на compose УСТАНОВКИ
(docker-compose.install.yml или имя ассета brabo-install-compose.yml).
И отказывают, когда dev-compose, как его вызывает скрипт, разрешил бы проект
brabo (COMPOSE_PROJECT_NAME=brabo в .env или в окружении). В reset
защита — ПЕРВЫЙ шаг, ещё до preflight, и отказ выходит как
RESET NÃO COMEÇOU.
Критерий — ФАЙЛ метки, а не имя проекта: установка
распознаётся при любом -p, и именно это делает защиту полезной против того, чего
имя не решает, — dev-compose, поднятого с -p brabo вручную,
COMPOSE_PROJECT_NAME и старого checkout с name: brabo (у которого нет
этой защиты, но продолжение аварии которого НОВЫЙ checkout отвергает).
Мерило существует в ДВУХ местах, JS (scripts/dev/instalacao-na-maquina.mjs) и
bash (recusar_se_ha_instalacao в scripts/dev/reset-total-lib.sh), потому что
spec reset запускается с поддельным node в PATH и должен доказать, что
сам скрипт отказывает. Оба задействованы соседними spec.
Неотвечающий Docker НЕ приводит к отказу: preflight говорит, что защита не выполнилась, и
продолжает (up без Docker ничего не поднимет), а в reset build, ещё до
первого эффекта, упал бы так же.
3. Миграция тех, кто уже разрабатывает: предупреждение, никогда отказ, никогда удаление.
Следующий pnpm dev создаёт ПУСТЫЕ тома brabo-dev_*; данные остаются в
brabo_*. Preflight ПРЕДУПРЕЖДАЕТ, когда находит том brabo_* с ключом, который ТОЛЬКО
dev-compose объявляет (*_node_modules, engine_build/deps/mix/hex), —
список ВЫВОДИТСЯ из двух файлов compose, никогда не копируется, — и отделяет, не
утверждая, чьи они, тома с общим для обоих ключом (pgdata, neo4j_data,
git_local_repos, project_workspaces…), которые могут принадлежать установке.
Процедура копирования (том за томом, cp -a, при остановленном Postgres) или
начала заново — в runbook, "Moving a dev environment to brabo-dev". Ни один
скрипт не удаляет том.
Последствия
- Разработчик действует один раз (поэтому ветка —
breaking/): роняет старый стек БЕЗ-v(docker compose -p brabo -f docker/docker-compose.yml down) и выбирает копировать данные или начать заново. Пока он этого не сделал, старый compose держит порты, и preflight говорит ровно это вместоport is already allocated. - Разработка на машине с установкой теперь требует сначала остановить
установку (
downбез-v: тома и данные остаются,up -dвозвращает её обратно). Это объявленная цена защиты по НАЛИЧИЮ, и её выбрал сопровождающий: раздельные имена уже делают сосуществование безопасным в обычном случае, но защита существует как раз для необычного случая — а защита, которая лишь смотрела бы на коллизию имён, пропустила бы старый checkout и ручной-pпри остановленной установке. Запустить оба ОДНОВРЕМЕННО по-прежнему невозможно в любом случае: они публикуют одни и те же порты. - Осиротевший том
brabo_*с общим ключом сам по себе неотличим между старым dev и установкой — предупреждение говорит это вместо утверждения. Runbook учит спрашивать (config_filesконтейнеров, исключительные ключи, была ли установка на машине). - Документация и команды, которые цитировали
brabo-api-1,brabo-postgres-1,brabo-ollama-1,brabo_pgdata… в контексте DEV, стали цитироватьbrabo-dev-*. Те, что говорят об УСТАНОВКЕ (томbrabo_project_workspaces, который измеряетinstall.sh, корень broker в установке), остаются как есть, потому что остаются правдой. Историческое повествование (старый CHANGELOG, принятые RN и ADR) не переписывается. - Метки
podлокального Prometheus становятсяbrabo-dev-api-1/brabo-dev-engine-1, реальным именем контейнера; ни один дашборд не фильтрует по значениюpod, только группирует.