# app_image Собирает docker-образ приложения **локально** (на control-хосте) и доставляет его на сервер через `docker save`/`load`. Тулчейн сборки (Go, node, …) на сервере не нужен — туда едет готовый образ. Роль — первый кирпичик деплоя: её задача, чтобы на сервере оказался образ `:`. Запуском приложения (рендер config и docker-compose, `docker compose up`) занимается остальная часть плейбука — позже это может стать отдельным кирпичиком. Тег образа — случайный `BUILD_ID`, который роль генерит на каждый прогон. Дедупликации по содержимому нет: каждый деплой везёт образ и пересоздаёт контейнер. Для ручного нечастого деплоя это осознанный выбор — простота важнее экономии одного рестарта. ## Контракт с приложением Приложение реализует **команду сборки образа** в своей рабочей директории. Роль — инициатор: она вызывает эту команду и передаёт ей случайный `BUILD_ID` через окружение. Команда обязана собрать **полный** образ и затегать его `:$BUILD_ID`. Пример реализации на Taskfile (тег из `$BUILD_ID`, по умолчанию `dev`): ```yaml image: desc: 'Полный docker-образ. Тег из $BUILD_ID (по умолчанию dev).' deps: [build] cmds: - docker build -t {{.BINARY}}:${BUILD_ID:-dev} . ``` `${BUILD_ID:-dev}` держит команду обратно совместимой: `task image` без переменной по-прежнему собирает `:dev` для локальной работы. ## Как работает 1. Роль генерит случайный `BUILD_ID` — это же и есть `app_image_tag`. 2. Гоняет `app_image_command` в `app_image_src_dir` → приложение собирает `:$BUILD_ID`. 3. `docker save` образа → копирует tar на сервер → `docker load`. 4. Отдаёт факт `app_image_tag`, чистит локальный тег и оба tar-файла. Локальный тег на control-хосте снимается по завершении (образ уже на сервере). Старые образы на сервере подчищает `docker image prune -af` по крону (см. `playbook-system.yml`). ## Переменные | Переменная | Обязат. | По умолчанию | Назначение | |---|---|---|---| | `app_image_name` | да | — | имя приложения; под ним тегается и живёт образ | | `app_image_src_dir` | да | — | рабочая директория приложения на control-хосте | | `app_image_command` | нет | `task image` | команда сборки образа (контракт); одна команда через `command`, без shell-синтаксиса | ## Выход - Факт **`app_image_tag`** — тег доставленного образа (= `BUILD_ID`). - На сервере — образ `:`. ## Пример ```yaml - name: 'Build and deliver application image' ansible.builtin.import_role: name: app_image vars: app_image_name: 'jellybit' app_image_src_dir: '{{ (playbook_dir, "..", "jellybit") | path_join }}' # далее compose-роль использует app_image_tag ```