Ответ
В GitLab CI/CD для сборки одного образа с несколькими тегами используется команда docker build с несколькими флагами -t. Вот пример реализации в .gitlab-ci.yml:
variables:
# Используем встроенный Container Registry GitLab
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
build_and_push:
stage: build
image: docker:latest
services:
- docker:dind
script:
# Логинимся в registry GitLab
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# Собираем образ один раз, но с двумя тегами: по хешу коммита и latest
- docker build -t $IMAGE_TAG -t $CI_REGISTRY_IMAGE:latest .
# Пушим оба тега
- docker push $IMAGE_TAG
- docker push $CI_REGISTRY_IMAGE:latest
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
Ключевые моменты:
- Одна сборка, несколько тегов: Команда
docker build -t image:tag1 -t image:tag2 .создает один образ с идентичными слоями, но разными именами. Это эффективнее, чем несколько сборок. - Осмысленные теги: Я использую
$CI_COMMIT_SHORT_SHAдля уникальной идентификации сборки от конкретного коммита иlatestдля указания на последнюю стабильную версию. - Правила пуша: Тег
latestя обновляю только при мерже в основную ветку (main/master), что задается в секцииrules. Для feature-веток пушится только тег с хешем.
Альтернативный подход с массивом тегов:
script:
- TAGS=("$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" "$CI_REGISTRY_IMAGE:latest")
- docker build $(printf "-t %s " "${TAGS[@]}") .
- for tag in "${TAGS[@]}"; do docker push "$tag"; done