GitlabでCI docker編

# まず最初はdocker
最近やっぱり```docker```にハマっているのもありますが簡単そうなのと環境的にはホストOSと環境が別れているような物なので環境を作り直すのに何かあった時は楽に復旧できそうです。（毎回作り直すので）

# インストール

```text:
$ docker pull gitlab/gitlab-runner:latest

latest: Pulling from gitlab/gitlab-runner
064f9af02539: Already exists 
390957b2f4f0: Already exists 
cee0974db2b8: Already exists 
c8144262002c: Already exists 
7a0374749bc1: Pull complete 
d73a93a666cb: Pull complete 
2fb68deec158: Pull complete 
a46cfb7c401d: Pull complete 
5566b54e1ba1: Pull complete 
Digest: sha256:01cb604ebb8ff1e5d7a788ce86172c86d20041aa88a7587dad812292d7daae79
Status: Downloaded newer image for gitlab/gitlab-runner:latest

$ 

```
```docker``` は別途インストールする必要はありますが、そこは省略(笑) 入っていればこの１行で入ります。

# 起動

```text:
$ docker run -itd \
		--name gitlab-runnder \
		-h gitlab-runnder \
		-v `pwd`/gitlab-runner/config:/etc/gitlab-runner
		gitlab-runnder:latest
```

## 起動確認

```text:
$ docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                                 NAMES
6050fe0176e8        gitlab-runnder:latest     "/usr/bin/dumb-init /"   2 minutes ago       Up 2 minutes                                              gitlab-runnder
528b306382ba        gitlab8:sameersbn8.11.2   "/sbin/entrypoint.sh "   11 minutes ago      Up 11 minutes       80/tcp, 0.0.0.0:22->22/tcp, 443/tcp   gitlab8
ba742054a60c        nginx:1.2.1               "/sbin/init 3"           30 minutes ago      Up 30 minutes       0.0.0.0:80->80/tcp                    nginx
```
```gitlab-runner``` 動いていますね。 ```gitlab```自体も```docker``` で動かしているので隣で動いているような感じになっています(笑)

# 登録
次に、```runner```を```Gitlab```に登録します。
事前に登録する前に、```Gitlab```側の```token```を知らないと登録できません。[^1]
```token``` には２種類あって以下の物があります。

- サーバー自体[^2]
- プロジェクト[^3]

## サーバーに登録
- 管理者エリアで```token```を確認します。<br>
右上「:wrench:」→「overview」→「runner」で表示されます。

こんな感じで```token```が赤く表示されます。

![スクリーンショット 2016-09-10 13.31.04.png](https://qiita-image-store.s3.amazonaws.com/0/12727/b4a3f70d-9318-c01b-d230-ce283b74083c.png "token表示")

### 登録コマンド
```token``` が分かったら次に登録処理のコマンドを実行します。

```text:
$ docker exec -it gitlab-runnder  gitlab-runner register
Running in system-mode.                            
                                                   
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
http://gitlab/ci
Please enter the gitlab-ci token for this runner:
xxLECy8zkytCyu8sSzdS
Please enter the gitlab-ci description for this runner:
[gitlab-runnder]: docker-runner
Please enter the gitlab-ci tags for this runner (comma separated):

Registering runner... succeeded                     runner=xxLECy8z
Please enter the executor: virtualbox, docker+machine, docker-ssh+machine, docker, docker-ssh, parallels, shell, ssh:
docker
Please enter the default Docker image (eg. ruby:2.1):
debian:7.9
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! 

```

するといくつか登録内容を聞かれるので入力します。

- ```http://gitlab/ci```<br> これは登録したい```gitlab```サーバーのURLに```ci```付けて、登録先を指定します。

- ```xxLECy8zkytCyu8sSzdS```<br> これはサーバーの```token```です。[^4]

- ```docker-runner```<br> ```runner```の名前ですね。```Gitlab``` 側で表示されても分かるように付けましょう。

- 次にタグですけど、カンマで複数登録できますしここでは空にしています。<br> ```CI``` 処理にこのタグで処理するという時の判断に使われます。

- ```docker``` 今回はdokcer編なのでdockerですね(笑)

- ```debian:7.9``` ```docker``` の時に聞かれるのですが使用するイメージ（default）を指定します。```docker hub```に登録されていイメージを指定します。[^5]

無事登録されると以下のように```token```が表示されていた画面の下へ先ほど登録した名前（説明？）で表示されます。

![スクリーンショット 2016-09-10 16.00.42.png](https://qiita-image-store.s3.amazonaws.com/0/12727/d38c4439-f3b5-3c30-022c-2a75b81ab7e8.png "gitlab-runner登録後の画面")

サーバーに登録された```runner```はプロジェクトの設定画面から登録されている```runner```を選ぶことができます。


## プロジェクトに登録
サーバーに間接的に登録して選ぶのではなくプロジェクト側の```token```で直接プロジェクトに登録します。
プロジェクトの```token```はプロジェクトを開いて右上に表示される「歯車アイコン」→「runner」をクリックすると管理エリアと同じように次のように表示されます。

![スクリーンショット 2016-09-10 16.13.36.png](https://qiita-image-store.s3.amazonaws.com/0/12727/a116c90f-6574-50d9-ebd8-4f1e2d3db22e.png "プロジェクトのtokunやrunnerのリスト")

管理エリアからすでにサーバーに登録されている物から選ぶことができますし、先ほどの登録コマンド時```token```入力でここでいう「-74uY9UmQun7dPuyaZTy」を登録すれば直接プロジェクトに登録することにします。一旦削除して、再度登録します。

### 登録コマンド

```text:
$ make regist
docker exec -it gitlab-runnder  gitlab-runner register
Running in system-mode.                            
                                                   
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
http://gitlab/ci
Please enter the gitlab-ci token for this runner:
-74uY9UmQun7dPuyaZTy
Please enter the gitlab-ci description for this runner:
[gitlab-runnder]: docker-runner
Please enter the gitlab-ci tags for this runner (comma separated):

Registering runner... succeeded                     runner=-74uY9Um
Please enter the executor: virtualbox, docker+machine, docker-ssh+machine, docker, docker-ssh, parallels, shell, ssh:
docker
Please enter the default Docker image (eg. ruby:2.1):
debian:7.9
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! 
```

```token``` 以外変わらないです。
するとプロジェクトの設定画面で次のようになります。

![スクリーンショット 2016-09-10 16.28.05.png](https://qiita-image-store.s3.amazonaws.com/0/12727/8abd6b45-3fd1-79e4-d662-162b170f4c01.png "プロジェクトと結びついたrunner")

# CI実行！！
これで準備は整いました！
早速実行してみましょう。ほかのネット上のサービスCIは特定のファイルに書いて```push```する事がトリガーなのが主流です。```gitlab```の場合はリポジトリの中に```.gitlab-ci.yaml```に実行手順を書くことによって実行されます。

## まずはCIの設定ファイル

```text:.gitlab-ci.yaml
image: debian:7.11

stages:
  - check
  - test
  - deploy

code_check:
  stage: check
  script:
    - echo "check1"
    - echo "check2"

test1:
  stage: test
  script:
    - echo "test"

deploy_production1:
  stage: deploy
  script:
    - echo "deploy(production)"
  only:
    - release/production

deploy_staging1:
  stage: deploy
  script:
    - echo "deploy(staging)"
  only:
    -  release/staging
```

デフォルトではdebian:7.9でしたが設定ファイルの方で7.11を指定します。
最初のブロックの```stages```ですがここで大枠の実行順序を指定します。

その下にはジョブと呼ばれるブロックがあり、最初には「code_check」があり、「stage: code_ceck」でstagesのどのステージにあたるかを書いています。
実行されるスクリプトは「scripts」の中で指定していきます。
ここでは実行スクリプトは単純に「echo」しているだけです。
次のステージ「test」ではジョブ「test1」があり。「deploy」のステージでは「production1」と「staging1」が用意されていますがそれぞれ、「only」で対象になるブランチが指定されています。
```.gitlab-ci.yaml``` と適当に一つソースを書いて```master```にプッシュします。続けて「release/staging」にもプッシュします。

プッシュされるとサーバー上では```.gitlab-ci.yaml```に従ってが実行され、以下のような実行結果になります。

![スクリーンショット 2016-09-11 14.07.39.png](https://qiita-image-store.s3.amazonaws.com/0/12727/04a04016-18c4-25c0-6ee2-b4a6f2d50621.png "パイプライン")

```master``` ブランチは「check」「test」が実行されていますが```release/staging```は「deploy」まで実行されているのが分かります。

それぞれのジョブ（ビルド）の結果はこんな感じになります。
前述の通りここでは```echo```だけですが、ログを見るとソースもクローンしてることが分かると思います。ソース中のシェルを指定するとコミットした物を実行できることが分かります。

チェック用の実行結果ですね。

![スクリーンショット 2016-09-11 14.08.05.png](https://qiita-image-store.s3.amazonaws.com/0/12727/ec632522-0bc0-b522-8463-8b760c3c5e69.png "")

デプロイが実行された結果です。

![スクリーンショット 2016-09-11 14.08.14.png](https://qiita-image-store.s3.amazonaws.com/0/12727/0135e95d-3d9f-ba28-767c-cf3938475161.png "スクリーンショット 2016-09-11 14.08.14.png")

このようにリリース先毎のシェルとブランチを用意しておけばそのブランチにマージしただけでデプロイが自動で走るような事ができます。
もちろんチェックやテストでエラーになるとそれ以降のステージはスキップされるので、変なソースがデプロイされるのも防ぎます。



[^1]: でないと全然知らない人に登録されますものね

[^2]: 一旦サーバーに登録して後でプロジェクトから使用する```runner```を選ぶという手順になります。
[^3]: 直接プロジェクトに使用する```runner```として登録します。
[^4]: もちろんそれぞれのサーバーは違うので読み替えてください。
[^5]: ローカルで自作のイメージも指定できますが、名前を少し変えないといけないのと```hub```に無かったけど仕方なくローカル使うよ的なワーニングがでます。あとは実行の設定ファイルでもイメージを指定できます。

# 関連
- [Gitlab日本語化(docker)インストール](http://qiita.com/takara@github/items/06577c49b7e1d3f68102)
- [Gitlabでlfs](http://qiita.com/takara@github/items/554edd6b22c5dee1be36)
- [GitlabでCI（イメージ）](http://qiita.com/takara@github/items/838d5828e38800f7f72b)


# 参考サイト
- [Run gitlab-runner in a container](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/install/docker.md)
- [gitlab-ci-multi-runner Advanced configuration](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md)