Gitlab CI
Здесь будет перечисление камней, на которые я наткнулся при работе с гитлабом.
Docker-in-Docker
Нужно, чтобы построение происходило в докере, а в результате публиковался другой докер-образ.
Для начала нужно настроить работу докера в докере.
Если у нас раннер зарегистрирован в гитлабе (shared runner), то нужно редактировать конфиг /etc/gitlab-runner/config.toml
Туда нужно вписать строки:
executor = "docker"
[runners.docker]
image = "docker"
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
Если же мы используем локальный билд в раннере командой build-runner exec docker <job-name>
, то конфиг тут не используется и нам придется передавать параметры аргументов командной строки:
gitlab-runner exec docker --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" <job-name>
Теперь вся сборка у нас будет происходить в контейнере образа docker, в котором доступна команда docker build
. А работать это будет благодаря пробросу docker.sock
, что означает что внутри образа будет использоваться на самом деле хостовый докер.
Дальше нужно настроить gitlab-ci.yml. Я делал так:
stages:
- build-build
- deploy-build
- build
- deploy
build_build_container:
stage: build-build
image: docker
script:
- docker pull "my-build" || true
- docker pull "my-build":$CI_COMMIT_REF_NAME || true
- docker build -t "my-build":$CI_COMMIT_REF_NAME --cache-from "my-build" --cache-from "my-build":$CI_COMMIT_REF_NAME ./build
tags:
- docker
deploy_build_container:
stage: deploy-build
image: docker
script:
- docker push "my-build":$CI_COMMIT_REF_NAME
tags:
- docker
build_release:
state: build
image: my-build:${CI_COMMIT_REF_NAME}
script:
...
- docker build -t "release":$CI_COMMIT_REF_NAME .
- build-build Строится билд-образ докера, в котором будет строиться проект на этапе
build
. В этом образе должны быть установлены все необходимые зависимости для построения всех проектов. - build-deploy Полученный билд-образ деплоится в реестр.
- build Билд подпроекта FC3 внутри билд-образа. Обычно на этом этапе нужно скомпилировать исходники, скопировать из в контекст построения докер-образа подпроекта, после чего запустить билд образа. Внутри билд-образа установлен докер, поэтому можно использовать команду
docker build
. - deploy Деплоятся образы, полученные на этапе
build
.
Пояснения:
- по адресу
./build/Dockerfile
лежит докерфайл нашего билд-контейнера, в котором установлены все необходимые зависимости - конструкция
--cache-from
нужна, чтобы использовать кэш с предыдущего построения билд-контейнера, иначе все зависимости будут строиться каждый раз. Обычное кэширование тут не используется, потому что мы строим внутри образа docker и все промежуточные слои остаются в нем и пропадают при следующем билде.
Git submodules
Если в проекте используются субмодули, то нужно в gitlab-ci.yml добавить переменную:
variables:
GIT_SUBMODULE_STRATEGY: normal
И в .gitmodules
изменить пути к репозиториям на относительные:
[submodule "project"]
path = project
url = ../../group/project.git
Это описано в документации. Проблема наступает, когда мы хотим использовать субмодули при построении в докере, который строится в докере.
Там придется мапить субмодули с хоста на те пути, куда указывает .gitmodules
:
gitlab-runner exec docker --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
--docker-volumes $(pwd)/.git/modules/project:/home/y/group/project.git \
job_name