Как настроить пайплайн для сборки одного Docker-образа с несколькими тегами?

Ответ

Это стандартная практика для тегирования образов. Я делаю это, указывая несколько тегов при выполнении команды docker build или используя возможности CI-инструмента.

Способ 1: Через Docker CLI (универсальный) В скрипте пайплайна можно передать несколько флагов -t:

docker build 
  -t myregistry.com/app:latest 
  -t myregistry.com/app:$CI_COMMIT_SHA 
  -t myregistry.com/app:v1.2.3 
  .
# Затем отправить все теги одним push
docker push myregistry.com/app --all-tags

Способ 2: Использование специальных Actions (GitHub Actions) Action docker/build-push-action удобно поддерживает множественное тегирование:

- name: Build and push Docker image
  uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: |
      ghcr.io/${{ github.repository }}:latest
      ghcr.io/${{ github.repository }}:${{ github.sha }}
      ghcr.io/${{ github.repository }}:${{ github.ref_name }}

Способ 3: GitLab CI с переменными окружения В GitLab CI удобно использовать предопределенные переменные:

build_image:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:latest -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $CI_REGISTRY_IMAGE:latest
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

Моя типичная стратегия тегирования:

  • latest: Для образа из последнего успешного коммита в основную ветку.
  • Хеш коммита ($CI_COMMIT_SHA): Для уникальной идентификации конкретной сборки. Это идеально для отладки и откатов.
  • Версия семантического версионирования (v1.0.1): Для релизных сборок, связанных с git-тегом.
  • Название ветки: Для сборок из feature-веток (например, feat-new-auth).

Ответ 18+ 🔞

А, ну это же классика, ебать мои старые костыли! Каждый раз, когда начинаешь с докером возиться, этот вопрос встаёт ребром. Как тегировать-то, чтобы потом не охуеть от бардака в реестре?

Смотри, тут всё просто, как три копейки. Главное — не быть распиздяем и не пихать один тег latest на всё подряд, а то потом будешь как слепой котёнок в подвале искать, какая сборка сломала прод.

Способ первый, самый что ни на есть прямой — через консоль докера. Ты просто накидываешь кучу флагов -t при сборке, как будто вешаешь бирки на уши корове. Собрал один раз — получил сразу три образа с разными именами. Красота, ёпта!

docker build 
  -t myregistry.com/app:latest 
  -t myregistry.com/app:$CI_COMMIT_SHA 
  -t myregistry.com/app:v1.2.3 
  .
# А потом разом всё это добро в реестр закидываешь
docker push myregistry.com/app --all-tags

Способ второй — для любителей GitHub Actions, там всё уже придумано за нас. Там есть специальная штука, которая умеет с тегами работать из коробки. Прописываешь список, и она сама всё сделает — и соберёт, и протегирует, и отправит. Удобно, блядь, волнение ебать!

- name: Build and push Docker image
  uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: |
      ghcr.io/${{ github.repository }}:latest
      ghcr.io/${{ github.repository }}:${{ github.sha }}
      ghcr.io/${{ github.repository }}:${{ github.ref_name }}

Способ третий — для тех, кто в Гитлабе сидит. Там тоже своя атмосфера, свои переменные. Всё уже готовое, бери и пользуйся. CI_COMMIT_SHORT_SHA — это вообще святое, чтобы по хешу найти ту самую сборку, которая всё сломала.

build_image:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:latest -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $CI_REGISTRY_IMAGE:latest
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

А теперь, чувак, слушай сюда мою стратегию, проверенную годами и слезами. Я всегда вешаю несколько тегов, как ёлочные игрушки:

  • latest: Это типа "самое свежее говно" из главной ветки. Удобно для тестов, но доверия к нему — ноль ебать, потому что в любой момент может накрыться медным тазом.
  • Хеш коммита ($CI_COMMIT_SHA): А вот это уже серьёзно. Каждая сборка получает свой уникальный номер, как татуировка. Хочешь откатиться на вчерашний рабочий билд? Пожалуйста, вот тебе его точный слепок. Спасение, блядь!
  • Номер версии (v1.0.1): Это уже для парадного выезда. Релизнул фичу, поставил git-тег — и сразу же докер-тег с красивым номером. Все сразу понимают, о чём речь.
  • Имя ветки: Ну, это для экспериментов. Собрал фичу из ветки feat-new-auth — и накатил тег с таким же именем. Показал тимлиду, он сказал "иди ты нахуй со своим кодом" — и ты спокойно удаляешь и ветку, и образ из реестра. Красота!

Вот и вся магия. Главное — не лениться и тегировать всё подряд, а то потом сам от себя охуеешь, пытаясь понять, какой из двадцати образов latest у тебя сейчас задеплоен.