Задачи по типу docker build не всегда нужно повторять. Банально, не всегда есть смысл заново собирать образ, который уже собран и ждем в Container Registry.
Поэтому такие задачи можно оставить на ручной запуск в gitlab-ci.yml:
Можно юзать разные версии одного сервиса, например, для тестирования.
docker:dind или “Docker in Docker”
Образ docker:dind (dind - docker indocker) нужен, если хочешь работать с docker и его командами, но не в хостовой системе.
dind share-ит свой сокет наружу, что позволяет, юзать команды docker из других контейнеров.
Самый частый use case - сборка образов, каждый из которых сохраняется локально и если каждый образ собирать на хостовой системе - там просто кончится место на диске, потому что образы заполнят всё. Поэтому берется контейнер с docker-ом, внутри которого уже собирается образ, который сохранится в рамках этого контейнера.
Вызывается как сервис:
... services: - docker:dind...
GitLab Container Registry
Контейнеры это stateless и immutable инфраструктура:
stateless: контейнеры не сохраняют состояние между запусками (в этом же и идея docker-а, что все данные должны быть внешними / в виде volume-ов).
immutable: контейнеры неизменяемы после создания, то есть, для обновлений создаются новые образы, а старые удаляются.
Это к тому, что всё, что произошло внутри контейнера будет потеряно, когда контейнер выключится. То есть, образ, собранный внутри контейнера, не сохранится никак в системе после выключения этого контейнера.
Поэтому нужен какой-нибудь Container Registry 👇.
GitLab Container Registry - доп. функция GitLab-а, позволяющая хранить docker-образы для проектов.
Для каждого проекта - свой реестр
Доступ по учетке в GitLab
Доступ через CI по токену
Для того, чтобы собрать и запушить образ в GitLab Container Registry нужно:
Используются GitLab CI predefined variables, чтобы собрать и запушить образ, который после этого будет доступен по подобной ссылке: registry.gitlab.com/arut-plus/docker-cicd-django/docker-cicd-django:master.
Но нужен образ с тегом latest, поэтому следующий шаг это реализует.
tag и push
docker tag ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_SLUG} ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:latestdocker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_PROJECT_NAME}:latest
Заново тегируется образ и опять пушится. В итоге в registry запушится один образ с двумя тегами.
В итоге, можно будет юзать ссылку на образ с тегом latest: registry.gitlab.com/arut-plus/docker-cicd-django/docker-cicd-django:latest
Ссылку на образ можно скопировать в Deploy > Container Registry.
В docker-compose.yml это будет выглядеть, например, так:
Ошибка при выполнении кода в блоке after_scriptне пометит пайплайн как failed. Это такое исключение, которое отличает after_script от before_script и script.
В gitlab-ci.yml можно включать блоки кода из других yaml файлов, находящихся в current или других репах.
Репозиторий должен быть частью группы
Если собираешься включать файлы из других репозиториев - последние должны быть частью группы в GitLab. Связано это с отличиями в правах и доступе по сравнению с личными репозиториями.
Есть, конечно, обходные пути, типа:
Кеш можно использовать для передачи данных между задачами в рамках одной ветки (key: ${CI_COMMIT_REF_SLUG}), одного коммита, в рамках всех пайплайнов для одного или нескольких (при некоторой настройке) раннеров.
Кеш хранится локально на хосте, где установлен раннер.
Используется для передачи состояния между этапами. Артефакты можно скачать прямо в GitLab WebUI - поэтому их и юзают для получения, например, тест-репортов или apk-пакетов. Артефакты сохраняет GitLab - runner здесь не при чем, ибо это зона ответственности самой платформы (GitLab).
Чтобы CI/CD переменные работали в не protected ветках, проверь, чтобы галочка не стояла на “Protect variable”, который Export variable to pipelines running on protected branches and tags only. Этот flag упомянается в доках здесь.