Как собрать Docker-образы в CI/CD job?

«Как собрать Docker-образы в CI/CD job?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В CI/CD пайплайне сборка Docker-образов выполняется в отдельном job с помощью команды docker build. Ключевые этапы: сборка, тегирование, аутентификация в registry и push.

Пример для GitLab CI (.gitlab-ci.yml):

build_image:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

Пример для GitHub Actions (.github/workflows/docker.yml):

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build Docker image
        run: docker build -t my-app:${{ github.sha }} .
      - name: Log in to Docker Hub
        run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
      - name: Push image
        run: docker push my-app:${{ github.sha }}

Оптимизации, которые я применяю:

  • Кэширование слоёв: Использую --cache-from и стратегии кэша в CI (например, cache: docker в GitLab CI).
  • BuildKit: Включаю DOCKER_BUILDKIT=1 для параллельной сборки и улучшенного кэширования.
  • Многоэтапные сборки: В Dockerfile разделяю этапы builder и runtime, чтобы итоговый образ содержал только необходимые артефакты.
  • Тегирование: Всегда тегирую образы по хэшу коммита ($CI_COMMIT_SHORT_SHA) для точного отслеживания, а также добавляю тег latest или тег версии при релизе.