2017年10月6日 星期五

gitlab CI 簡單測試環境建置

先簡單說明建置的環境, 及規劃透過 gitlab CI 的流程

gitlab 的部分:
  • 用 docker  跑 gitlab
  • 用 docker  跑 gitlab-runner

要跑 CI 的環境:
  • 用 docker 跑三個 container,  nginx + php-fpm + mysql
  • 網站使用  laravel 放在 host 上, 以 volume 的方式掛在 php-fpm container

gitlab CI 流程:
  1. 在 host 上將 laravel code push 到 gitlab
  2. 依設定會觸發 gitlab-runner 開始跑 CI
  3. gitlab-runner 以指定的 docker image 為環境進行測試

大部分的設置流程在這篇寫得很清楚了, 這篇記錄一些遇到的問題及測試的方法.

  1. 我所有的環境都在同一台機器上面 (google cloud) 跑的, 所以在 gitlab container run 的時候, 設定的 GITLAB_HOST 為 device docker0 的 ip,  預設為 172.17.0.1
    如果 gitlab 和 gitlab-runner 不在同一台機器的話, 就要設定為 gitlab 那台的對外 ip
  2. .gitlab-ci.yml 裡有設定 tags 的話, gitlab 會去找設定 tags 一樣的 runner.
    這是前面文件裡沒提到的部分, 例如在 .gitlab-ci.yml 設定 tags 為 docker , 但是沒有 runner 的 tags 設定為 docker 時, 會從 gitlab 的 pipeline 裡看到 fail , 會有錯誤訊息如下
    
    This job is stuck, because you dont have any active runners online with any of these tags assigned to them
    

  3. gitlab-runner 的設定檔 config.toml 裡, 可以設定要掛載哪些 volume, 可以參考官方文件
    在 [runners.docker] section 裡, 設定格式為
    volumes = ["/home/duan/data/run/php:/run/php", "/home/duan/mysite:/var/www/mysite"]
    這表示會掛載 2 個 volume 分別到 /run/php 和 /var/www/mysite



因為 gitlab 不熟, 也沒用過 gitlab CI , 全部都用 docker 來跑感覺更複雜, 看文件時好像都很順, 自己實作時卻發現很多問號. 然後之前也沒寫過/用過 laravel 的 unit test , 所以還手動跑到  php-fpm 的 container 裡執行 phpunit  , 看會不會和 host 裡執行有不一樣的結果.

花了不少時間 (總共大約兩個工作天) 查資料, 設定和除錯, 最後看到 gitlab 的 jobs 出現 phpunit 測試完成的訊息, 還真是頗高興地. 最後附上主要的設定檔及一些相關的說明


config.toml

concurrent = 1

[[runners]]
  name = "my_first_runner"
  url = "http://gitlab_ip:port/ci"
  token = "the_token_from_gitlab"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "php-fpm"
    privileged = false
    disable_cache = false
    volumes = ["/home/duan/data/run/php:/run/php", "/home/duan/mysite:/var/www/mysite"]
  [runners.cache]
    Insecure = false
.gitlab-ci.yml , 執行 phpunit 做測試

stages:
  - build

build-test:
  stage: build
  tags:
    - "docker"
  image:
    name: php-fpm
  script:
    - cd /var/www/mysite && ./vendor/bin/phpunit
跑 nginx + php-fpm + mysql 的 docker-compose.yml , 為了方便不想修改 nginx image 內的設定檔, 所以掛載 nginx 設定檔來用.

web:
  image: nginx
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - /home/duan/data/nginx:/etc/nginx
    - /home/duan/mysite:/var/www/mysite
  links:
    - php

php:
  image: duanli/php-fpm
  volumes:
    - /home/duan/mysite:/var/www/mysite
    - /home/duan/data/run/php:/run/php
  links:
    - mysql

mysql:
  image: mysql
  volumes:
    - /home/duan/data/mysql:/var/lib/mysql
  environment:
    - MYSQL_ROOT_PASSWORD=rootpassword
    - MYSQL_DATABASE=database
    - MYSQL_USER=user
    - MYSQL_PASSWORD=password
跑 gitlab 的 docker-compose.yml , 包含 gitlab + redis + postgresql , 這個 image 作者有提供很完整的 yml 設定方式

version: '2'

services:
  redis:
    restart: always
    image: sameersbn/redis:latest
    command:
    - --loglevel warning
    volumes:
    - /home/duan/data/redis:/var/lib/redis:Z

  postgresql:
    restart: always
    image: sameersbn/postgresql:9.6-2
    volumes:
    - /home/duan/data/postgresql:/var/lib/postgresql:Z
    environment:
    - DB_USER=user
    - DB_PASS=password
    - DB_NAME=dbname
    - DB_EXTENSION=pg_trgm

  gitlab:
    restart: always
    image: sameersbn/gitlab:9.5.5
    depends_on:
    - redis
    - postgresql
    ports:
    - "10080:80"
    - "10022:22"
    volumes:
    - /home/duan/data/gitlab:/home/git/data:Z
    environment:
    - DEBUG=false

    - DB_ADAPTER=postgresql
    - DB_HOST=postgresql
    - DB_PORT=5432
    - DB_USER=user
    - DB_PASS=password
    - DB_NAME=dbname

    - REDIS_HOST=redis
    - REDIS_PORT=6379

    - GITLAB_HOST=172.17.0.1
    - GITLAB_PORT=10080
    - GITLAB_SSH_PORT=10022
    - GITLAB_RELATIVE_URL_ROOT=
    - GITLAB_SECRETS_DB_KEY_BASE=password
    - GITLAB_SECRETS_SECRET_KEY_BASE=password
    - GITLAB_SECRETS_OTP_KEY_BASE=password
gitlab-runner 的 docker-compose.yml

version: '2'

services:
  gitlab-runner:
    restart: always
    image: gitlab/gitlab-runner:v1.1.0
    volumes:
    - /home/duan/data/gitlab-runner:/etc/gitlab-runner:Z
    - /run/docker.sock:/var/run/docker.sock:Z

沒有留言: