https://habr.com/post/429824/В каждом уважающем себя проекте должны участвовать QA инженеры. Ежедневно перед ними будет стоять задача проверки выполнения задач в отдельных ветках. Очень часто процесс перехода на нужную ветку, сборки и тестирования занимает много времени, к тому же, локально не всегда возможно полностью воссоздать максимально идентичное боевому окружение.
Цель данной статьи — показать простую технику настройки стенда на несколько веток. Данная статья написана разработчикам от разработчика, поэтому вряд ли будет представлять существенный интерес для профессиональных DevOps инженеров.
Требования:
- Gitlab (bare metal/cloud)
- Выделенный сервер
- Свободный домен
Шаг первый: настройка Gitlab
- Установите Gitlab Runner на Вашем выделенном сервере
- Создайте воркера, поддерживающего сборки docker образов
- Включите Container Registry
Шаг второй: настройка сервера
- Установите Docker
- Установите Compose
- Создайте пользователя:
# создаем пользователя для деплоя образов, разрешаем ему работу с докером
$ sudo adduser deployer
$ sudo groupadd docker
$ sudo usermod -aG docker deployer
# генерим ssh ключи
$ su deployer
$ ssh-keygen -t rsa
(when asked for a passphrase, enter no passphrase)
# разрешаем подключение к серверу с только что созданным ключом
$ cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
- Настройте traefik (сервер, проксирующий запросы к Docker контейнерам на базе их ярлыков(лейблов)):
$ sudo mkdir -p /opt/traefik
$ docker network create web
# файлы настроек docker-compose & traefik упрощены до предела и должны быть достаточно понятными
/opt/traefik/docker-compose.yml
version: '2'
services:
traefik:
image: traefik:1.4.6
restart: always
ports:
- 80:80
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
container_name: traefik
networks:
web:
external: true
/opt/traefik/traefik.toml
Замените DOMAIN.COM на свой домен.
debug = true
checkNewVersion = true
logLevel = "ERROR"
defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[retry]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "DOMAIN.COM"
watch = true
exposedbydefault = false
- Запустите traefik:
cd /opt/traefik && docker-compose up -d
- Добавьте A запись для DOMAIN.COM вида '*' — IP выделенного сервера.
Шаг третий: подготовка репозитория
- Добавьте в корень репозитория Dockerfile:
FROM node:8.9 as build-deps
WORKDIR /usr/src/app
COPY package.json ./
RUN npm i
COPY . ./
RUN npm run build
FROM nginx:1.12-alpine
COPY --from=build-deps /usr/src/app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Измените
npm run build
на вашу команду сборки. Аналогично отредактируйте путь
/usr/src/app/dist
изменив dist на вашу директорию сборки.
Подробнее почитать про структуру и команды докерфайа можно тут.
- Добавьте .gitlab-ci.yml файл с секцией сборки образа:
image: docker:stable
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
GITLAB_DOMAIN: gitlab.com
services:
- docker:dind
stages:
- build
build_staging:
stage: build
script:
- export GITLAB_DOMAIN=gitlab.com
- export CONTAINER_IMAGE=$GITLAB_DOMAIN/frontend/main/image
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $GITLAB_DOMAIN
- docker pull $CONTAINER_IMAGE:$CI_COMMIT_REF_SLUG || true
- export URL="Host:${CI_COMMIT_REF_NAME}.tests.DOMAIN.COM"
- docker build -t $CONTAINER_IMAGE:$CI_COMMIT_REF_SLUG . --label "traefik.backend=${CI_COMMIT_REF_NAME}" --label "traefik.frontend.rule=${URL}"
- docker push $CONTAINER_IMAGE:$CI_COMMIT_REF_SLUG
- Добавьте приватный ключ deployer@DOMAIN.COM в настройки репозитория(Settings -> CI/CD -> Variables) как SSH_PRIVATE_KEY
- Добавьте deploy секции:
stages:
- build
- deploy
/// ....
deploy_staging:
stage: deploy
image: kroniak/ssh-client:3.6
script:
- mkdir ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- ssh deployer@DOMAIN.COM "docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $GITLAB_DOMAIN"
- ssh deployer@DOMAIN.COM "docker stop frontend_${CI_COMMIT_REF_SLUG}" || true
- ssh deployer@DOMAIN.COM "docker rm frontend_${CI_COMMIT_REF_SLUG}" || true
- ssh deployer@DOMAIN.COM "docker rmi GITLAB-DOMAIN.COM/frontend/main/image:${CI_COMMIT_REF_SLUG}" || true
- ssh deployer@DOMAIN.COM "docker run --name frontend_${CI_COMMIT_REF_SLUG} --network=web -d $GITLAB_DOMAIN/frontend/main/image:${CI_COMMIT_REF_SLUG}"
environment:
name: review/$CI_COMMIT_REF_NAME
url: http://${CI_COMMIT_REF_NAME}.tests.DOMAIN.COM
on_stop: stop_staging
stop_staging:
stage: deploy
image: kroniak/ssh-client:3.6
variables:
GIT_STRATEGY: none
script:
- mkdir ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- ssh deployer@DOMAIN.COM "docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN GITLAB-DOMAIN.COM"
- ssh deployer@DOMAIN.COM "docker stop frontend_${CI_COMMIT_REF_SLUG}" || true
- ssh deployer@DOMAIN.COM "docker rm frontend_${CI_COMMIT_REF_SLUG}" || true
- ssh deployer@DOMAIN.COM "docker rmi $GITLAB_DOMAIN/frontend/main/image:${CI_COMMIT_REF_SLUG}" || true
when: manual
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
Приведенных выше шагов достаточно для получения следующего результата:
- Каждый новый коммит в ветку иницирует сборку и развертку последнего актуального кода по адресу %branch_name%.tests.DOMAIN.COM
- В Gitlabе включен механизм окружений, позволяющий в пару касаний создавать/удалять/открывать задеплоенные образы
Следующие шаги:
- Настроить отдельную секцию для сборок мастера. В случае мастера разумно тэгать образ через COMMIT_SHA
- Добавить конфиги к nginxу в докере
- Пробросить параметры сборки бандла через ARG и ENV механизмы докерфайла
- Настроить использование кэша из образа для сборок
За основу взята статья.