GitLab CI: Часть 4, этап spawn в .gitlab-ci.yml

May 25, 2017 16:25 · 623 words · 3 minute read gitlab gitlab ci

В предыдущей статье цикла о настройке GitLab CI мы познакомились со специальным файлом .gitlab-ci.yml, в котором описываются инструкции для раннеров, рассмотрели несколько примеров и подготовили «скелет» для внедрения continuous integration в проекте.

Как и обещал, каждый из этапов (stage) мы будем рассматривать отдельно, так что для начала давайте разберемся с этапом spawn из нашего файла .gitlab-ci.yml!

Сразу стоит отметить, что названия этапов (stage) и задач (jobs) не являются зарезервированными или ключевыми словами, поэтому их можно называть как угодно (лишь бы вы понимали, что там написано).

В данном случае самый первый этап из continuous integration я обозначил как spawn (порождение) — запуск всех контейнеров, необходимых при сборке проекта. В конфигурационном файле .gitlab-ci.yml этот этап выглядит следующим образом:

...
spawn_containers:
  stage: spawn
  before_script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
  script:
    - set -o allexport; . ./docker/.env.staging.lc
    - docker-compose -f docker/docker-compose-build.yml up -d
  only:
    - develop
    - docker
...

Задачи, которые необходимо выполнить раннеру описываются в секции script. В нашем примере это две задачи — первая считывает переменные окружения из файла /docker/.env.staging.lc, вторая — создает и запускает контейнеры, описанные в конфигурационном файле /docker/docker-compose-build.yml.

Примечание. Обратите внимание, пути к конфигам указываются относительно корня проекта, ведь файл .gitlab-ci.yml должен лежать именно в корне проекта.

Как оказалось в процессе тестирования, перед выполнением задач, описанных в секции script необходимо залогиниться в локальный Docker Registry, где хранятся нужные нам образы. Действия, которые необходимо выполнить перед основными задачами (из секции script) обозначить довольно легко с помощью ключевого слова before_script. Соответственно, действия которые выполняются после основных задач, должны описываться в секции after_script.

Переменные $CI_JOB_TOKEN и $CI_REGISTRY — это специальные (предопределенные) переменные, весь список которых находится здесь.

С помощью ключевого слова only мы также определяем для каких веток нужно производить все описанные действия (develop и docker), здесь можно также использовать регулярные выражения.

Запускаемые контейнеры описаны в конфигурационном файле docker-compose-build.yml и выглядят так:

version: '2'
services:
### Applications Code Container #############################
    applications:
        container_name: application
        image: tianon/true
        volumes:
            - ../:${PROJECT_PATH}
### Workspace Utilities Container ###########################
    workspace:
        container_name: workspace
        image: registry.gitlab.lc:5000/develop/ed:workspace-ed-sq
        volumes_from:
            - applications
### PHP-FPM Container #######################################
    php-fpm:
        container_name: php-fpm
        image: registry.gitlab.lc:5000/develop/ed:php-fpm-ed-sq
        volumes_from:
            - applications
        expose:
            - "9000"
        links:
            - workspace
### Node+npm Container ######################################
    node:
        container_name: node
        image: registry.gitlab.lc:5000/develop/ed:node-npm-ed-sq
        volumes_from:
            - applications
        ports:
            - "${NODE_PORT}:${NODE_PORT}"
### Redis Container #########################################
    redis:
        container_name: redis
        image: registry.gitlab.lc:5000/develop/ed:redis-ed-sq
        volumes:
            - redis:/data
        ports:
            - "${REDIS_PORT}:${REDIS_PORT}"
        links:
            - php-fpm
### Memcached Container #####################################
    memcached:
        container_name: memcached
        image: registry.gitlab.lc:5000/develop/ed:memcached-ed-sq
        volumes:
            - memcached:/var/lib/memcached
        ports:
            - "${MC_PORT}:${MC_PORT}"
        links:
            - php-fpm
### Websocket Container #####################################
    websocket:
        container_name: websocket
        restart: always
        image: registry.gitlab.lc:5000/develop/ed:websocket-ed-sq
        volumes_from:
            - applications
        ports:
            - "${WS_PORT}:${WS_PORT}"
### Volumes Setup ###########################################
volumes:
    memcached:
        driver: "local"
    redis:
        driver: "local"

Все docker-образы были заранее собраны и загружены в локальный docker registry проекта. Самый первый запуск задачи spawn_containers в процессе continuous integration может занять до нескольких минут (раннер должен скачать образы), но при последующих запусках это время сократится до нескольких секунд.

В моем случае, запуск контейнеров занимает 18 секунд, а на вкладке pipelines детали выполнения задачи выглядят следующим образом:

Running with gitlab-ci-multi-runner 1.10.0 (4a71a97)
Using Docker executor with image registry.gitlab.lc:5000/develop/ed:tmaier-dc-ssh ...
Starting service registry.gitlab.lc/develop/ed:my-docker-dind ...
Using locally found image version due to if-not-present pull policy
Waiting for services to be up and running...
Using locally found image version due to if-not-present pull policy
Running on runner-9e68759f-project-8-concurrent-0 via c7662d5025ba...
HEAD is now at 679227f2ed Merge branch 'feature/LK-7341' into 'develop'
From http://gitlab.lc:10087/develop/ed
  679227f2ed..635e14c14a  develop    -> origin/develop
Checking out 635e14c1 as develop...
Skipping Git submodules setup
$ docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
Login Succeeded
$ set -o allexport; . ./docker/.env.staging.lc
$ docker-compose -f docker/docker-compose-build.yml up -d
Creating network "docker_default" with the default driver
Creating application
Creating websocket
Creating workspace
Creating node
Creating php-fpm
Creating redis
Creating memcached
Build succeeded

С первым этапом из файла .gitlab-ci.yml разобрались, в следующей статье рассмотрим второй этап — процесс сборки проекта.

tweet Share