Мы подошли к этапу, который превращает разрозненные инструменты в единую систему. До этого момента мы научились писать Dockerfile для упаковки приложений и работать с переменными GitLab CI/CD для защиты данных. Теперь наша задача — объединить эти навыки, чтобы при каждом обновлении кода система автоматически создавала актуальный образ и сохраняла его в надежном месте.
В современной разработке ручная сборка и отправка образов с локальной машины — это риск. Можно забыть обновить зависимости, использовать не ту версию базового образа или оставить лишние файлы в слоях. Автоматизация гарантирует, что в продакшн попадет именно тот код, который прошел проверку в репозитории.
Реестр контейнеров: хранилище образов
Прежде чем запускать сборку, нужно определить, куда мы отправим результат. Реестр контейнеров (Container Registry) — это специализированное хранилище для Docker-образов. В GitLab есть встроенный реестр, интегрированный с правами доступа к проекту.
Для взаимодействия с реестром в пайплайне нужны три команды:
docker login— авторизация в хранилище.docker build— создание образа из Dockerfile.docker push— отправка готового образа в реестр.
Мы не прописываем логины и пароли в коде. GitLab автоматически предоставляет временные переменные для каждой задачи: $CI_REGISTRY_USER и $CI_JOB_TOKEN.
Технология Docker-in-Docker
Когда задача в GitLab Runner запускается внутри Docker-контейнера, возникает сложность: как запустить Docker внутри Docker? Эта технология называется Docker-in-Docker (или сокращенно DinD).
Для работы DinD в конфигурации пайплайна подключают специальный сервис. Это позволяет внутреннему контейнеру обращаться к Docker-демону для выполнения команд сборки.
На Схеме 1 показано, как происходит взаимодействие между компонентами во время выполнения задачи.
Практическая реализация пайплайна
Настроим файл .gitlab-ci.yml для автоматической сборки Python-приложения. Мы создадим образ и пометим его уникальным тегом, используя короткий хэш коммита ($CI_COMMIT_SHORT_SHA). Это обеспечит прослеживаемость: вы всегда будете знать, из какой версии кода собран конкретный образ.
Пример настройки стадии сборки с использованием DinD:
stages:
- build
build_image:
stage: build
image: docker:24.0.5
services:
- docker:24.0.5-dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
script:
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAGВ этом примере происходит сборка Docker-образа в CI, где каждый шаг логируется. Если docker build завершится с ошибкой (например, из-за опечатки в Dockerfile), пайплайн остановится, и вы сразу об этом узнаете.
Пример с ошибками в безопасности и тегировании:
# ПЛОХО: статические пароли и тег latest
script:
- docker login -u my_admin -p P@ssw0rd123 # ОПАСНО: пароль в открытом виде
- docker build -t my-app:latest . # ПЛОХО: тег latest перезаписывается, историю не отследить
- docker push my-app:latestОптимизация и российская специфика
При работе с российскими облачными провайдерами (Yandex Cloud, VK Cloud) учитывайте доступность базовых образов. В корпоративных сетях часто настраивают зеркала (mirrors) для ускорения загрузки 🛰️
Задание на самопроверку:
- Возьмите Dockerfile вашего Python-проекта.
- Создайте в корне проекта файл
.gitlab-ci.ymlс блокомbuild, как в примере выше. - Добавьте в секцию
scriptкомандуdocker images, чтобы увидеть список созданных слоев в логах пайплайна. - После успешного запуска проверьте раздел Deploy -> Container Registry в GitLab — там должен появиться ваш первый автоматизированный образ 📦
Мы научились создавать готовые к работе образы. Но просто хранить их в реестре недостаточно. Чтобы превратить их в работающие сервисы, нужно научиться управлять конфигурацией серверов.
В следующей теме мы разберем Ansible — инструмент для автоматизации настройки инфраструктуры, куда мы будем развертывать наши контейнеры.
Понравился урок?
Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей
Продолжить в Telegram