Files
ansible-roles/roles/app_image

app_image

Собирает docker-образ приложения локально (на control-хосте) и доставляет его на сервер через docker save/load. Тулчейн сборки (Go, node, …) на сервере не нужен — туда едет готовый образ.

Роль — первый кирпичик деплоя: её задача, чтобы на сервере оказался образ <app_image_name>:<tag>. Запуском приложения (рендер config и docker-compose, docker compose up) занимается остальная часть плейбука — позже это может стать отдельным кирпичиком.

Тег образа — случайный BUILD_ID, который роль генерит на каждый прогон. Дедупликации по содержимому нет: каждый деплой везёт образ и пересоздаёт контейнер. Для ручного нечастого деплоя это осознанный выбор — простота важнее экономии одного рестарта.

Контракт с приложением

Приложение реализует команду сборки образа в своей рабочей директории. Роль — инициатор: она вызывает эту команду и передаёт ей случайный BUILD_ID через окружение. Команда обязана собрать полный образ и затегать его <app_image_name>:$BUILD_ID.

Пример реализации на Taskfile (тег из $BUILD_ID, по умолчанию dev):

image:
  desc: 'Полный docker-образ. Тег из $BUILD_ID (по умолчанию dev).'
  deps: [build]
  cmds:
    - docker build -t {{.BINARY}}:${BUILD_ID:-dev} .

${BUILD_ID:-dev} держит команду обратно совместимой: task image без переменной по-прежнему собирает <app>:dev для локальной работы.

Как работает

  1. Роль генерит случайный BUILD_ID — это же и есть app_image_tag.
  2. Гоняет app_image_command в app_image_src_dir → приложение собирает <app_image_name>:$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).
  • На сервере — образ <app_image_name>:<app_image_tag>.

Пример

- 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