CI/CD ツール "drone" をOn-Premise で導入する。

## はじめに

普段の業務で CI/CD ツールを導入されている方は多いのではないでしょうか？ 今回、勉強のために自分でdroneというツールをOn-Premise版で入れてみました。その導入においての軌跡を書いていきたいと思います。

## Drone とは？

JenkinsやCircle CIと同じように 継続的インテグレーションや継続的デリバリー(CI/CD)の実現のためのツールです。
公式： https://www.drone.io/

droneには On-Premises と Cloud 版があり、コンテナをベースとしたCIツールです。

## 導入手順

### ngrokで Global な URL を取得する

ngrokを使ったことない方は[こちら](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)を参照。
簡単に手順だけ書くと、

- ngrokでユーザー登録
- ngrokコマンドのインストールを行う
- ngrokを起動する

になります。

今回は8080ポートにしてみます。

```bash
ngrok http 8080
```

起動画面
![ngrok-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/692f5f07-b525-1745-30a0-d02e9a010737.png)


生成されたURLを Drone Host に使います。ngrokを用いずにGlobal な URL を用意しても大丈夫です。

### GitHubでOAuth Applicationを作成

[https://github.com/settings/applications/new](https://github.com/settings/applications/new)

以下の項目を入力します。

- Application Name

これは好きなのでOK。僕は「Drone」にしました。

- HomePage URL

こちらは先ほど取得したngrok url を入れます。

```
ex) https://hogehoge.ngrok.io/
```

- Authorization callback URL

`https://{ngrokのurl}/authorize/` と入力します。

```
ex) https://hogehoge.ngrok.io/authorize/
```
　
この設定が完了すると **Client ID / Client Secret** が取得できるので、確認できていればOKです。(後ほど使用)
![pict01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/488e411e-14ab-05b8-a697-2df866a2f0f0.png)

### docker-compose.ymlを作成する

まずdrone-server用のディレクトリを作成します。

```bash
mkdir drone-server && cd drone-server
```

drone-server 内に `docker-compose.yml` を作成します。
docker-compose.yml は公式にもサンプルがあるのでそれを参考にするのが簡単だと思います。
([公式のサンプル](https://0-8-0.docs.drone.io/installation/))

ただし、今回は ngrok の port と整合性を取らないと上手くいかないです。
servicesの配下にdrone-serverについて書いていきます。

```yml:docker-compose.yml

services:
  drone-server:
    image: drone/drone:0.7.3
    ports:
      - 8080:8000
```

 のように設定しました。

### volumesの設定

servicesのdrone-serverに volumesの設定を行います。因みにvolumesとはデータを永続化できる場所を指定する箇所です。こちらがないと動作不良になるので注意してください。

```yml:docker-compose.yml
volumes:
      - ./drone:/var/lib/drone/
```

### environmentの設定

後述するenvファイルでの環境変数をこちらに設定できるようにしておきます。

```yml:docker-compose.yml
    environment:
      - DRONE_OPEN=true 
      - DRONE_HOST=${DRONE_HOST} 
      - DRONE_GITHUB=true 
      - DRONE_GITHUB_URL=${DRONE_GITHUB_URL} 
      - DRONE_GITHUB_CLIENT=${DRONE_GITHUB_CLIENT} 
      - DRONE_GITHUB_SECRET=${DRONE_GITHUB_SECRET}
      - DRONE_SECRET=${DRONE_SECRET} 
      - DRONE_GITHUB_PRIVATE_MODE=true 
```

### drone-agentを設定する。
変更を検知してもビルド回すためにも drone-agentのサーバーの設定は必要です。
drone-serverと同様にvolumesとenvironmentの設定をします。

```yml:docker-compose.yml
drone-agent:
    image: drone/drone:0.7.3
    command: agent
    restart: always
    depends_on:
      - drone-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_SERVER=ws://drone-server:8000/ws/broker
      - DRONE_SECRET=${DRONE_SECRET}

```

### 最終的なdocker-compose.yml

以下になります。

```yml:docker-compose.yml
version: "2"

services:
  drone-server:
    image: drone/drone:0.7.3
    ports:
      - 8080:8000
    volumes:
      - ./drone:/var/lib/drone/
    restart: always
    environment:
      - DRONE_OPEN=true
      - DRONE_HOST=${DRONE_HOST} 
      - DRONE_GITHUB=true       
      - DRONE_GITHUB_URL=${DRONE_GITHUB_URL}
      - DRONE_GITHUB_CLIENT=${DRONE_GITHUB_CLIENT} 
      - DRONE_GITHUB_SECRET=${DRONE_GITHUB_SECRET}
      - DRONE_SECRET=${DRONE_SECRET} 
      - DRONE_GITHUB_PRIVATE_MODE=true 

  drone-agent:
    image: drone/drone:0.7.3
    command: agent
    restart: always
    depends_on:
      - drone-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_SERVER=ws://drone-server:8000/ws/broker
      - DRONE_SECRET=${DRONE_SECRET}

```

### envファイルを作成する

docker-compose.ymlができたら、同階層に .envファイルを作成します。
上記で取得したhost等を設定してあげます。DRONE_HOSTには先ほど取得した ngrok url を入れてください。ここはdrone server のパブリックなアドレスになります。

```bash:.env
DRONE_GITHUB_URL=https://github.com
DRONE_GITHUB_CLIENT={github OAuthで取得した Client ID}
DRONE_GITHUB_SECRET={github OAuthで取得した Client Secret}
DRONE_SECRET={お好きな文字列}
DRONE_HOST=https://hogehoge.ngrok.io
```

### droneにログインして認証する

ngrok url にアクセスすると以下のような画面になるはずです。

![pict5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/199affde-5eb2-bef5-323a-c612ef053792.png)

loginを押して認証画面へ

![pict03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/1d8fdffa-69fa-41ea-1225-48ec23e23e65.png)

「Authorize」押下で認証完了すればdroneが使えるようになります。
droneを回したいプロジェクトを指定してあげましょう。

## 実際にdroneがまわるかテスト

今回はnotion blogに導入してみます。
ディレクトリ内に .drone.yml を作ります。
.drone.yml の書き方は[公式を参考にしました。](https://docs.drone.io/pipeline/docker/syntax/images/)
とりあえずテスト用のサンプル。

```yml:.drone.yml
# test
pipeline:
  hello:
    # ステップ毎にイメージを指定する必要あり
    image: alpine:3.6
    # Dockerコンテナ起動時のエントリポイントとして以下のコマンドは実行される。
    # 各コマンドをかく。
    commands:
      - echo "Hello World"
```

test/lint/build を実行できるようにしたサンプルは[こちら](https://jhcoder.com/write-drone-yml)

では実際に notion-blog に変更を加えて pushし droneを回してみます。
黄色時は実行中なので 完了(緑色) / 失敗 (赤色) になるまで待ちましょう。
以下のようになっていれば問題なく完了しています。

![iOS__(18).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/f900f43e-d205-f3d2-7675-3dad8214dee4.jpeg)

先ほど`.drone.yml`に書いた `hello` が実行されてるのがわかりますね。

![pict05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/1fee6dad-a2bd-73d1-e758-4b22f5d8a04c.png)

## おわりに
あとは公式をみながら、`.drone.yml`を追記してカスタマイズしたいですね。実際に活用しようと思うと、testやbuild、deploy等を入れるケースが多いのかなと思います。
この記事がdrone 導入の際の参考になれば幸いです。