CI for frontend: Gitlab, Traefik, Docker
Every self-respecting project should involve QA engineers. Every day they will be faced with the task of verifying the execution of tasks in separate branches. Very often, the process of switching to the desired branch, assembly and testing takes a lot of time, moreover, it is not always possible locally to completely recreate the most identical combat environment.
The purpose of this article is to show a simple technique of setting up a stand for several branches. This article is written by developers from the developer, so it is unlikely to be of significant interest to professional DevOps engineers.
Requirements:
The above steps are enough to get the following result:
Next steps:
Based on the article.
The purpose of this article is to show a simple technique of setting up a stand for several branches. This article is written by developers from the developer, so it is unlikely to be of significant interest to professional DevOps engineers.
Requirements:
- Gitlab (bare metal / cloud)
- Dedicated server
- Free domain
Step One: Configure Gitlab
- Install Gitlab Runner on your dedicated server
- Create a docker that supports docker builds of images
- Turn on Container Registry
Step Two: Server Setup
- Install Docker
- Install Compose
- Create a user:
# создаем пользователя для деплоя образов, разрешаем ему работу с докером $ 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
- Configure traefik (server proxying requests to Docker containers based on their labels (labels)):
$ sudo mkdir -p /opt/traefik $ docker network create web # файлы настроек docker-compose & traefik упрощены до предела и должны быть достаточно понятными
/opt/traefik/docker-compose.ymlversion: '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
Replace DOMAIN.COM with your domain.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
- Run traefik:
cd /opt/traefik && docker-compose up -d
- Add an entry for DOMAIN.COM of the form '*' - IP of the dedicated server.
Step three: prepare the repository
- Add the Dockerfile to the root of the repository:
FROM node:8.9as 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;"]
Changenpm run build
on your build team. Similarly edit the path/usr/src/app/dist
changing dist to your build directory.
You can read more about the structure and commands of Docherfaye here . - Add the .gitlab-ci.yml file with the image assembly section:
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
- Add the private key deployer@DOMAIN.COM to the repository settings (Settings -> CI / CD -> Variables) as SSH_PRIVATE_KEY
- Add deploy sections:
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}" || truewhen: manual environment: name: review/$CI_COMMIT_REF_NAME action: stop
The above steps are enough to get the following result:
- Each new commit into a branch initiates the assembly and development of the latest actual code at% branch_name% .tests.DOMAIN.COM
- Gitlab includes an environment mechanism that allows you to create / delete / open closed images in a couple of touches.
Next steps:
- Set up a separate section for the wizard builds. In the case of the master, it is reasonable to tag the image via COMMIT_SHA
- Add configs to nginx in docker
- To forward the build parameters of the bundle through the ARG and ENV mechanisms of the dockfile
- Configure use of cache from image for assemblies
Based on the article.