GitLab のコンテナネイティブなパイプライン機能を使ってみる

オンプレミスで自前のサーバーを建て GitLab をセルフホストしている現場をよく見るようになってきました。GitLab 曰く、セルフホスト市場で 2/3 のシェアを獲っているそうです。

今や GitLab はソースコード管理に留まらず DevOps 含めたワンストップのサービスになろうとしているようです。

docs.gitlab.com

CI/CD が標準装備で、月2000分まで無償枠です。GitLab にアカウントを作成して、CI を試してみました。

1つのリポジトリに対して1つの CI/CD パイプラインを定義できます。パイプラインは .gitlab-ci.yml という名前の YAML ファイルで記述します。

build1:
  stage: build
  script:
    - echo build

test1:
  stage: test
  script:
    - echo "run a test suite"

test2:
  stage: test
  script:
    - echo "run a lint test"

deploy1:
  stage: deploy
  script:
    - echo "Do your deploy here"

git clone がないのは対象リポジトリが固定だからです。デフォルトの stage 名と実行順は buildtestdeploy で、ステージ名が同じ場合は並行実行になります*1。上記のパイプラインは以下のように、test1test2 がパラレルに実行されます。

f:id:kondoumh:20190414060306p:plain

前回の Jenkins Build Pipeline と同様に Spring Boot アプリのサンプルを使います。

github.com

リポジトリは GitHub から簡単にインポートできます。プロジェクトのルートに .gitlab-ci.yml を配置すれば CI Runner がコミットの度にパイプラインを実行してくれます。

f:id:kondoumh:20190414013930p:plain

Runner は GitLab で稼働していますが、Jenkins の JNLP エージェントのようにローカル環境にインストールして実行することも可能です。

docs.gitlab.com

今回作ったパイプライン定義です。BuildTest の2ステージ構成で、それぞれ Java 8 と Docker in Docker のコンテナイメージを使います。Build ステージで Spring Boot アプリの JAR を作成 (ビルドと単体テスト実行、アーカイブが流れます)。artifacts で生成した JAR のパスを書いて、Test ステージの docker-compose から呼ばれる Dockerfile でコンテナに JAR を COPY しています。

Build:
  image: java:8
  stage: build
  script: ./mvnw package
  artifacts:
    paths:
      - target/sb-sample-service.jar

Test:
  image: docker:latest
  services:
    - docker:dind
  stage: test
  script:
    - apk add --no-cache py-pip python-dev libffi-dev openssl-dev gcc libc-dev make curl
    - pip install docker-compose
    - docker-compose up -d
    - sleep 30
    - 'curl -X POST "http://docker:8080/api/user/" -H "accept: */*" -H "Content-Type: application/json" -d "{ \"id\": 1, \"name\": \"Mike\"}"'
    - 'curl -X GET "http://docker:8080/api/usr/1" -H "accept: */*"'
    - docker-compose down

Test ステージではコンテナ内でアプリのコンテナを起動して curl で REST API を叩きます。docker-compose をインストールするために Python をインストールして pip install でインストールしています。curl もインストール。

docker-compose up -d でアプリと Mongo DB のコンテナを起動、curl で REST API を叩きます。この時アプリのホスト名は docker を使います*2

パイプライン実行結果グラフのノードをクリックすると実行ログを確認できます。

f:id:kondoumh:20190414071031p:plain

f:id:kondoumh:20190414011906p:plain

今回は使っていませんが、ステージ毎に only セクションでビルドの種類を指定でき、MR (Merge Request) 単位のビルドや Master ビルドを定義して GitLab フローを回すのに最適です。

build:
  stage: build
  script: ./build
  only:
  - master

test:
  stage: test
  script: ./test
  only:
  - merge_requests

deploy:
  stage: deploy
  script: ./deploy
  only:
  - master

docs.gitlab.com

Jenkins のように複数のリポジトリを取得して複合的なパイプラインを作るということはできません*3が、今回見たようにコンテナがネイティブにサポートされているので、クリーン環境でテストできますし、慣れれば環境構築も楽ですね。

Microsoft にも Azure DevOps があるので GitHub とインテグレートしたりするのかな?

azure.microsoft.com

*1:stages セクションを定義してカスタマイズ可能です。

*2:これが分からずちょっとハマりました。

*3:将来的に計画はされてるようです。