Vagrant で OSS 版 drone を試す

とりあえず試しに導入してみたかったので、ローカルの Vagrant 上の Ubuntu で
drone を動かして github のリポジトリをビルドできるようにしてみた。

## drone とは

https://github.com/drone/drone これ。

drone は Go で書かれた CI 。ビルドは Docker の中で実行する。
クラウド版の https://drone.io/ もあるけど、 OSS 版はかなり UI が違う。

## Vagrant で Ubuntu を用意。

```bash
vagrant init ubuntu/trusty64
```

これで `Vagrantfile` が作られるので次のようにする。
(コメント部分は省略)

```bash
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.ssh.forward_agent = true
end
```

起動して、ssh で入る。

```bash
vagrant up
vagrant ssh
```

## drone の起動

vagrant 上で次のコマンドを実行する。

```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install libsqlite3-dev docker.io
wget downloads.drone.io/master/drone.deb
sudo dpkg --install drone.deb
sudo start drone
```

これだけで drone が動かせるので、ホストマシンのブラウザで次のURLにアクセスする。

```
http://localhost:8080
```

drone のページが表示されればOK

![top01.png](https://qiita-image-store.s3.amazonaws.com/0/8985/0d2155bf-6e20-a168-d4cc-21f110f381bb.png)


## ngrok で web hook を local で受け取れるようにする

drone は github 等からの web hook を受け取ってビルドを実行するため、
localhost でも web hook を受け取れるようにする必要がある。

https://ngrok.com/ を使うと一時的に localhost に外部からアクセスできるようになるのでこれを使う。

ngrok をダウンロードして、次のコマンドを実行する。

```bash
ngrok -hostname="kbaba1001drone.ngrok.com" 8080
```

`ngrok` はオプション無しだと適当に `hostname` を設定するが、後々のために固定したいので指定する。
これにより `http://kbaba1001drone.ngrok.com` で `localhost:8080` にアクセスできるようになる。

## github でログインできるようにする

drone を動かすための最低限の設定として、 github や BitBucket などホスティングサービスに
アクセスできるようにする設定が必要となる。

今回は github にアクセスしたいので、 https://github.com/settings/applications/new で
次ように設定する。

- **Application name:** localhost drone
- **Homepage URL:** http://kbaba1001drone.ngrok.com
- **Authorization callback URL:** http://kbaba1001drone.ngrok.com/api/auth/github.com

登録すると `Client ID` と `Client Secret` が発行されるので、これを drone に設定する。
drone の設定は `/etc/drone/drone.toml` に書く。

`/etc/drone/drone.toml` の `[github]` の項目をコメントアウトして先ほどの `Client ID` と `Client Secret` を書く。

```diff
- [github]
- client=""
- secret=""
+ [github]
+ client="xxxxxxxxxxxxxx"
+ secret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# orgs=[]
# open=false
```

設定が終わったら drone を再起動する。

```bash
sudo restart drone
```

これで github にログインできるようになれば成功。

![github_login.png](https://qiita-image-store.s3.amazonaws.com/0/8985/d6f9c1d8-ae6d-0a72-178a-b82acc4a5cc8.png)

## docker のセットアップ

drone はビルドをすべて docker 上で行う。
ビルドを行うための基礎となる image が配布されているので、とりあえずそれをいれる。

```bash
sudo docker pull bradrydzewski/ubuntu
sudo docker pull bradrydzewski/base
```

あとはビルドする言語別の docker が必要となるので下記を参考にして淹れる。

- https://github.com/drone/drone/blob/v0.2.1/README.md#images
- https://github.com/drone/images#builders

前者は image が配布されているが後者は自分で Dockerfile から build する。

例えば Ruby 2.0.0 でビルドしたい場合、次のようにする。

```bash
sudo docker pull bradrydzewski/ruby:2.0.0
```

## `.drone.yml` の用意

ビルドしたいリポジトリのルートディレクトリに `.drone.yml` を用意してビルドの設定を書く。

例えば postgresql を使っている rails アプリをビルドする場合、次のような感じにする。

```yaml
image: ruby2.0.0
services:
  - postgres
env:
  - SECRET_KEY_BASE=xxxxxxxxxxxx
script:
  - mkdir -p /tmp/bundle
  - sudo chown -R ubuntu:ubuntu /tmp/bundle
  - gem update bundler
  - bundle install -j8 --path /tmp/bundle
  - cp config/database_drone.yml.example config/database.yml
  - bundle exec rake db:create db:migrate spec
cache:
  - /tmp/bundle
```

## drone にリポジトリを登録する

drone でリポジトリを検索して activate すると github に web hook が自動的に設定される。
この状態でコミットを push したり Pull Request を作ると drone でビルドが走る。

初回のビルドは postgres など docker image を取得するので時間がかかる。

気長に待って失敗か成功をすればok

![build_success.png](https://qiita-image-store.s3.amazonaws.com/0/8985/54760141-53e9-60f2-3dc9-32c33ad3be2f.png)

## まとめ

github や ruby 向けの設定を取り除いた Vagrantfile 。

```rb
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
 
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "private_network", ip: "192.168.33.10"
  config.ssh.forward_agent = true
  config.vm.provider "virtualbox" do |vb|
    vb.memory = 2048
    vb.cpus = 2
  end
 
  config.vm.provision :shell, inline: <<-SHELL
apt-get update
apt-get -y upgrade
apt-get install -y libsqlite3-dev docker.io
wget downloads.drone.io/master/drone.deb
dpkg --install drone.deb
rm drone.deb
docker pull bradrydzewski/ubuntu
docker pull bradrydzewski/base
  SHELL
end
```