Gitlab CI и docker-compose

13.05.2022 / devops
Рассмотрим вариант эффективного использования docker-compose в CI конвейере при помощи Gitlab Runner с shell executor'ом

Недавно мы уже рассматривали CI конвейер Gitlab, с тех пор проект, для которого затевался весь DevOps, стал расти и потребовался другой подход в организации непрерывной интеграции.

Теперь нужно запускать ряд последовательных операций анализа и тестов:

После всего перечисленного мы можем с бОльшей долей уверенности выпускать релиз + при помощи автоматизации этих процессов нивелировать человеческие ошибки

Организация

Можно было бы запихнуть это все в один job, но как-то плохо все в одной куче потому что не видно на каком этапе произошел провал, поэтому раскидаем каждый этап на свой job.

Задания этапов конвейера

Ситуацию осложняет факт наличия нескольких сервисов (кроме php нужен mysql) для прохождения последнего этапа, поэтому используется docker-compose (иначе можно было бы сделать по другому).

А еще есть composer, он нужен на каждом этапе, как и зависимости проекта. Но в конце каждого job'a в терминале можно увидеть:

Cleaning up project directory and file based variables
Job succeeded

Это значит что каждый job очищает после себя артефакты, среди которых зависимости проекта, а без зависимостей не можем продолжать работу. Но если закэшировать нужные пути тогда очистки не будет.

В проекте уже ипользуется файл docker-compose-dev.yml для организации изолированной среды разработки, можно его использовать, так как среда может измениться с новой версией и желательно прямо в репозитории иметь актуальный конфиг

Executor gitlab-runner'a должен быть shell, через терминал будем поднимать композицию контейнеров.

.gitlab-ci.yml

Схема работы:

Теперь перенесем эту схему на конфиг:

# кэширование артефактов между job'ами
cache:
  paths:
    - vendor/

stages:
  - analysis
  - test

# поднятие композиции контейнеров
pre-job:
  stage: .pre
  script:
    - docker-compose -f docker-compose-test.yml up -d --force-recreate --build
    - docker-compose -f docker-compose-test.yml exec -T php composer install

# анализ code-style
analysis-cs-job:
  stage: analysis
  script:
    - docker-compose -f docker-compose-test.yml exec -T php composer run-script cs

# стстический анализ
analysis-lint-job:
  stage: analysis
  script:
    - docker-compose -f docker-compose-test.yml exec -T php composer run-script lint

# unit тесты
test-unit-job:
  stage: test
  script:
    - docker-compose -f docker-compose-test.yml exec -T php vendor/bin/phpunit --colors=always --coverage-text --bootstrap tests/Unit/bootstrap.php tests/Unit/
  coverage: '/\s+Lines:\s{2,}(\d+[,.]\d+%)/'

# server тесты
test-server-job:
  stage: test
  script:
    - docker-compose -f docker-compose-test.yml exec -T php composer run-script test-server

# системные тесты
test-system-job:
  stage: test
  script:
    - docker-compose -f docker-compose-test.yml exec -T php composer run-script test-system

# обязательное завершение работы композиции контейнеров
post-job:
  stage: .post
  when: always
  script:
    - docker-compose -f docker-compose-test.yml down

Результаты

Конфиг docker-compose-dev.yml используемый для разработки на машинах разработчиков пошел в автоматизированную тестовую среду на CI конвейер, что привело к единообразию среды разработки и тестов/анализов.

Из подручных средств был организован один из шагов непрерывной интеграции. Ну не нсовсем из подручных, тесты писались самостоятельно специально для этого.