Files
transcriber/docs/adr/ADR-2026-08-15-node-in-container-not-on-machine.md
T
av 663021f712 приложение собрано каркасом и вшито в бинарник
- заведён каталог web/ — Vue 3, роутер пятой версии, сборка Vite; собранное
  вшивается через go:embed и раздаётся корневым маршрутом: разметка на
  неизвестном пути вне корней сервиса, отказ контракта внутри корня
- перечень корней сервиса стал единой точкой и порождает регистрацию маршрутов,
  а не описывает её; журнал раздачи пишет исход и длину пути, но не сам путь
- шаг front зовёт Node контейнером docker — Biome, юнит-тесты Vue и сборка
  входят в гейт, а в Dockerfile появилась ступень приложения
2026-08-15 18:51:05 +03:00

4.7 KiB
Raw Blame History

Node зовётся контейнером, а не ставится на машину разработчика

Решение

Шаг сборки приложения гоняет установщик пакетов и сборщик внутри контейнера, а не вызывает их из PATH:

Требованием к машине разработчика становится docker, которым и так собирается образ, — второго устанавливаемого окружения сверх ffmpeg не появляется вовсе.

Образ сборочного окружения берётся из ступени Dockerfile, а не объявляется вторым числом в Taskfile.yml.

Почему

Довод в дизайне назван прямо:

Так снимается расхождение, которое иначе завелось бы молча: версия Node на машине разработчика и версия в образе — два разных числа, и собранное ими приложение различается ровно тогда, когда различаются они.

Отвергнуты два очевидных подхода, и оба с названной ценой. Поставить Node на машину — вводит второе устанавливаемое окружение и разъезжается с версией в образе. Дать выбор — контейнер или локальный Node — это второй способ делать одно и то же, и собранное ими различалось бы в зависимости от того, у кого что стоит.

Почему это ADR

Запись проходит триггер намеренным отказом от очевидного подхода: поставить Node на машину — ровно то, что делают по умолчанию, и отказ от этого надо объяснить один раз, а не на каждом вопросе «почему у нас нельзя просто npm run build».

Что это меняет в прежнем решении

ADR-2026-08-11-spa-on-vue записал последствием, что «машина разработчика получает второе требуемое окружение сверх ffmpeg», и подразумевал под ним Node. Окружением оказался docker. Сам выбор фреймворка и наличие шага сборки это не пересматривает, поэтому статуса «заменено на» у той записи нет: заменена не она, а толкование одного её последствия.

Последствия

  • + версия сборочного окружения живёт одним местом — ступенью Dockerfile, — и своего шага сверки ей не нужно.
  • + собранное в наборе проверок и собранное в образе совпадает, потому что совпадает окружение сборки, а не потому что «обычно совпадает».
  • набор проверок перестаёт работать без docker, и отказ этот приходит кодом окружения. Тем же кодом приходит отказ реестра пакетов: сетезависимых шагов в наборе становится два вместо одного.
  • контейнер ходит под тем же пользователем, что и вызвавший, а кэш установщика уводится наружу — обе частности обязательны: без них собранное ляжет от root, а зависимости будут тянуться заново каждый прогон.
  • вес и время самой ступени в образе неизвестны: финальный образ от неё не растёт (ступень в рабочий слой не копируется), а время сборки решением владельца от 2026-08-15 не замеряется вовсе.