Довольно часто мы используем GitLab CI для докеризации наших приложений. Но как запустить контейнер Docker из GitLab Container Registry? Можно ли использовать Docker Compose? Делимся переводом статьи, в которой автор отвечает на эти вопросы, и рассказывает о функции services keyword в GitLab CI. Она позволяет запустить один или несколько образов Docker и связать их с вашим заданием.  Для этого сценария я создал приложение Node.js, которое предоставляет API. Таким образом, текущий пайплайн состоит из следующих этапов: build, где устанавливаются все зависимости test, на котором выполняются все модульные тесты package, где приложение докеризируется, и образ отправляется в GitLab Container Registry. Для справки, вот как выглядит .gitlab-ci.yml на этом этапе: В этом сценарии используется shared runner инфраструктура GitLab.com, где GitLab раннеры используют Kubernetes executor. Для некоторых Docker executor может потребоваться указать переменную DOCKER_HOST. Вы узнаете об этом, если получите эту ошибку: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? Этот подход НЕ подходит для shell executors. или Следующим логичным шагом было бы проведение приемочных тестов, выполнение нескольких команд cURL в контейнере Docker или, что еще лучше, использование Postman/Newman для тестирования API. Как же запустить Docker-контейнер в рамках конвейера GitLab CI? Локально я собрал и протестировал контейнер с помощью docker build и docker run. То же самое должно быть возможно и в рамках конвейера, верно? Задание build docker image уже предоставляет очень хороший шаблон для использования Docker в GitLab. Поэтому я войду в GitLab Container Registry и запущу созданный ранее образ. Чтобы упростить конвейер, я НЕ указывал никаких версий для образов docker и docker:dind и не создавал никаких тегов для созданного образа. В реальном сценарии я бы сделал и то, и другое. К сожалению, следующая установка завершится с ошибкой: curl: (7) Failed to connect to localhost port 3000 after 5 ms: Connection refused Но почему? Локально все работало просто отлично. Чтобы объяснить причину, позвольте мне познакомить вас с сервисами GitLab CI. Как вы видели, задание, создающее конвейер, использовало ключевое слово services для указания образа docker:dind. В двух словах, сервисы GitLab предоставляют вам возможность запускать дополнительные контейнеры Docker и связывать их с вашим образом (тем, который вы указали в ключевом слове image). Один из наиболее типичных случаев использования — когда вам нужна база данных, API или другой сервис, который можно вызвать по сети. Вот несколько ключевых аспектов, которые вам необходимо запомнить: Образ или образы, указанные в services, могут быть доступны только через сетевое соединение. Образ или образы, указанные в services, должны открывать службу на заданном порту. В противном случае они бесполезны в данном контексте. Вы не сможете подключаться или выполнять команды командной строки на контейнерах, запущенных как службы. Использование сервисов НЕ похоже на определение файла docker-compose.yaml Если у вас локально установлен Docker, вы можете открыть окно терминала и ввести команду, например: На выходе получится что-то вроде Однако если я попытаюсь выполнить такие команды, как docker pull, docker build или docker run, то получу ошибку, подобную этой: Error response from daemon: dial unix docker.raw.sock: connect: connection refusedCannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? На этом этапе позвольте мне процитировать документацию Docker: Docker использует клиент-серверную архитектуру. Клиент Docker общается с демоном Docker, который выполняет всю работу по созданию, запуску и распространению ваших контейнеров Docker. Клиент Docker и демон могут работать в одной системе, или вы можете подключить клиента Docker к удаленному демону Docker. Клиент Docker и демон взаимодействуют с помощью REST API, через сокеты UNIX или сетевой интерфейс. На локальном уровне вы не задумываетесь об этом, поскольку и клиент, и демон установлены на одной машине. Но в GitLab все обстоит несколько иначе. Итак, в GitLab образ docker — это просто клиент. Образ docker:dind - это демон Docker, который запускается как служба, предлагая доступные по сети сервисы. Клиент может взаимодействовать с демоном через сетевой интерфейс. В предыдущем примере приложение Node.js, открывающее API на порту 3000, было запущено демоном Docker в контейнере docker:dind. Поэтому использование localhost не сработает, так как API запущен в другом контейнере. К счастью, GitLab автоматически генерирует имя хоста для соответствующей службы. В данном случае это имя хоста — docker. Поэтому мы можем получить доступ к приложению с помощью cURL, адаптировав команду для использования docker вместо localhost. Однако такой подход громоздок, поскольку теперь мы запускаем Docker в Docker в Docker. Время выполнения только этого задания составляет 61 секунду. Должен быть лучший способ. Ключевое слово services позволяет нам указать как публичный образ Docker, доступный на Dockerhub, так и использовать наш частный GitLab Container Registry. curl api testing:  stage: acceptance  image: curlimages/curl  services:     - name: $CI_REGISTRY_IMAGE      alias: banking-api  script:     - curl http://banking-api:3000/status | grep "UP" Я расширил конфигурацию, указав alias. Я не был уверен, какое имя хоста сгенерирует GitLab, и предпочел указать его самостоятельно. Следуя принципам, использованным в cURL, я могу добавить новое задание, которое использует публичный образ Newman Docker для запуска существующей коллекции Postman. Обратите внимание, что я ввел переменную окружения Postman baseUrl во время выполнения. Не удается подключиться к демону Docker по адресу unix:///var/run/docker.sock. Запущен ли демон Docker? Для некоторых исполнителей Docker может потребоваться указать переменную DOCKER_HOST на уровне конвейера или задания. или  Надеюсь, это руководство помогло вам получить доступ к вашему приложению dockerize из вашего CI-конвейера GitLab.  Полезные ссылки: GitLab CI/CD Services Docker Docs — Docker overview GitLab Runner Issue tracker: Localhost not working like it does on my physical computers Окунись в мир практических задач по CI/CD, пополни портфолио реальными кейсами и вырасти до нового уровня в своей профессии на Навыкуме по CI/CD в Слёрме. Навыкум позволит тебе: Наработать около 20 часов практики. Добавить в своё резюме и базовые, и реальные кейсы по CI/CD. «Подсмотреть» лучшие практики в свою копилку знаний. Попасть в комьюнити сильных специалистов с чатом поддержки. Доступ к нему навсегда. 👉 Оставить заявку