# Локальная сборка образов вместо Yandex Container Registry **Приоритет:** Средний Три приложения деплоятся через Yandex Container Registry: homepage, transcriber, remembos. Схема одинаковая — образ собирается локально и пушится в `cr.yandex/...` (`playbook-homepage-registry.yml`, `playbook-transcriber-registry.yml`), плейбук деплоя делает `docker_login` с `yc_oauth_token`, compose тянет образ по registry-пути с зашитым в git тегом (`transcriber:2fc5a56-1761210134`, `remembos:v0.2.0`, `homepage-nginx:latest`). У remembos registry-плейбука нет вовсе — образ пушится руками. Роль `app_image` (канон в `~/projects/private/ansible-roles`) делает то же самое без registry: собирает образ на control-хосте командой самого приложения (контракт — `task image`, получает `BUILD_ID` через окружение), везёт его на сервер через `docker save`/`load` и отдаёт факт `app_image_tag` для compose. Обкатана в umbar на jellybit и trackers. Что станет иначе: из деплоя уходят внешний реестр и OAuth-токен, тег образа перестаёт быть константой в git, а `inv pl -- homepage` становится полным деплоем — сейчас сборка живёт в `task deploy` репозитория homepage, который сам зовёт `ansible-playbook`. Шаги: - ~~завендорить роль `app_image`~~ — **сделано**: подписка в `SYNCED_ROLES`, копия в `roles/app_image`; механика переноса — [shared-roles-sync](shared-roles-sync.md) - ~~homepage: завести в Taskfile таск `image` с тегом из `$BUILD_ID`, перевести плейбук на роль, удалить `playbook-homepage-registry.yml` и registry-переменные из `vars/homepage.yml`~~ — **сделано**: таск `image` собирает node-образ, сайт и nginx-образ одной командой; `task deploy`/`deploy-with-ansible` удалены, деплой целиком — `inv pl -- homepage` - ~~remembos: контракта сборки нет (есть Dockerfile, нет Taskfile) — завести таск `image`, убрать зашитый тег из compose~~ — **сделано**: в репозитории remembos появился `Taskfile.yml` с таском `image`, плейбук зовёт роль, compose тянет `remembos:{{ app_image_tag }}` с `pull_policy: never`; `docker_login` из плейбука убран - ~~transcriber: исходников на этой машине нет~~ — **сделано**: репозиторий нашёлся (`~/projects/private/transcriber`), Taskfile сведён к таску `image`, плейбук переведён на роль; `vars/transcriber.images.yml` с зашитым тегом удалён вместе с ритуалом «yq + коммит тега» из старого `task deploy` - осталось: убрать `yc_oauth_token` и `yc_container_registry` из vault — на них больше никто не ссылается; дальше по [narrow-secret-scopes](narrow-secret-scopes.md) Готово, когда ни один плейбук не делает `docker_login`, `cr.yandex` не встречается в репозитории, а все три приложения деплоятся одним `inv pl -- `. Осталось только вычистить vault и прогнать деплой каждого приложения. Цена размена: дедупликации по слоям больше нет — каждый деплой везёт полный образ, и для сборки нужен локальный docker с тулчейном. Для ручного нечастого деплоя это осознанный выбор (так решено в самой роли). Замеры архивов (`docker save`): homepage — 61 МБ, transcriber — 73 МБ, remembos — 21 МБ. Пересекается с [gitea-runner-on-demand](gitea-runner-on-demand.md): если сборки уедут в CI, доставка образа на сервер снова становится отдельным вопросом. Связано: playbook-homepage.yml, playbook-transcriber.yml, playbook-remembos.yml, vars/homepage.yml, vars/transcriber.yml, roles/app_image, files/{homepage,transcriber,remembos}/docker-compose.template.yml.