gogs + drone.io をつくる docker-compose.yml

手元で試せる drone.io 環境が欲しかったので作った。

# docker-compose.yml の中身

ローカル環境前提で毎回作りなおす形で作ってるのでそれぞれのコンテナにはとくに `restart: always` は入れてないが、`docker-machine` 立ち上げ時に常に実行する形にするなら入れること。

```yml
consul:
  container_name: consul
  image: gliderlabs/consul-server
  net: host
  command: -bootstrap

registrator:
  container_name: registrator
  # リトライが出来ないので restart する形で対処
  restart: on-failure
  net: host
  image: gliderlabs/registrator
  command: consul://localhost:8500
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock

drone:
  container_name: drone
  image: drone/drone
  ports:
    - "8000:8000"
  environment:
    - GIN_MODE=release
    - SERVER_ADDR=:8000
    - REMOTE_DRIVER=gogs
    - REMOTE_CONFIG=http://gogs-3000.service.consul:3000?skip_verify=true
    - DATABASE_DRIVER=mysql
    - DATABASE_CONFIG=root:drone@tcp(mysql.service.consul:33060)/drone?parseTime=true
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  volumes_from:
    - drone-data

drone-data:
  container_name: drone-data
  image: busybox
  net: none
  command: /bin/sh
  volumes:
    - /var/lib/drone

drone-db:
  container_name: drone-db
  image: mysql:5.6
  ports:
    - "33060:3306"
  environment:
    - MYSQL_ALLOW_EMPTY_PASSWORD=false
    - MYSQL_ROOT_PASSWORD=drone
    - MYSQL_DATABASE=drone

gogs:
  container_name: gogs
  image: gogs/gogs
  ports:
    - "3000:3000"
    - "22022:22"
  volumes_from:
    - gogs-data

gogs-data:
  container_name: gogs-data
  image: busybox
  net: none
  command: /bin/sh
  volumes:
    - /data

gogs-db:
  container_name: gogs-db
  image: mysql:5.6
  ports:
    - "33061:3306"
  environment:
    - MYSQL_ALLOW_EMPTY_PASSWORD=false
    - MYSQL_ROOT_PASSWORD=gogs
    - MYSQL_DATABASE=gogs
```

## 手順

以下 OSX 前提で話をすすめる。Windows の場合は dnsmasq の手順が使えないので後ろにある軽量版の `docker-compose.yml` を使ったうえで docker-compose の実行からはじめること。

### dnsmasq の設定

`docker-compose` を実行する前に [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) の設定 [^1][^2] に

```
# 192.168.99.100 は `docker-machine ip [name]` のアドレスに置換すること
address=/consul/192.168.99.100#8600
```

を入れる。dnsmasq と docker-machine 再起動後 consul を介して

  - http://drone.service.consul:8000
    - drone.io のアドレス
  - http://gogs.service.consul:3000
    - gogs のアドレス
  - http://consul.service.consul:8500
    - consul のアドレス

でアクセスできる。

## docker-compose の実行

dnsmasq 設定後 `docker-compose up -d` すると

  - [consul](https://github.com/hashicorp/consul/)
    - [registrator](https://github.com/gliderlabs/registrator) でポートが開いてるコンテナを自動登録するように設定
  - [drone.io](https://github.com/drone/drone)
  - [gogs](https://github.com/gogits/gogs)
  - [mysql](http://www.mysql.com/)

が立ち上がって簡易 GitHub-like + CI 環境が docker 上で作られる。

## gogs のインストール

gogs は一回インストール画面に入るので以下を入力する。

  - Database Type
    - MySQL
      - 軽量版の場合は SQLite を選択する
  - Host
    - mysql.service.consul:33061
  - User
    - root
  - Pass
    - gogs
  - SSH Port
    - 22022
  - Application URL
    - http://gogs-3000.service.consul:3000
      - 軽量版の場合は http://192.168.99.100:3000 を入力
  - Enable Offline Mode
    - :white_check_mark: を入れる
  - Enable Captcha
    - :white_check_mark: を外す

これで gogs が利用可能になる。レポジトリを作り、リモートを登録して push すれば gogs に反映される。この状態で drone.io にログインすれば drone.io と gogs の連携ができるはず。

# 軽量版の docker-compose.yml

上は consul とか mysql とかゴテゴテに入ってるので軽量版も。DNS サーバを立てるのが面倒な Windows 版の Docker を使うときはこっちのほうが使いやすいと思う。

 - gogs をインストールするときは SQLite　を選択する
 - IP アドレスが `192.168.99.100` で直打ちなので注意
   - なのでアクセスするときはそれぞれ以下になる
     - drone にアクセスするときは http://192.168.99.100:8000
     - gogs にアクセスするときは http://192.168.99.100:3000
   -  普通 `docker-machine` が最初に立ち上げる時の VM の IP アドレスは `192.168.99.100` になるはず

## docker-compose.yml の中身

```yaml
drone:
  container_name: drone
  image: drone/drone
  ports:
    - "8000:8000"
  environment:
    - GIN_MODE=release
    - SERVER_ADDR=:8000
    - REMOTE_DRIVER=gogs
    - REMOTE_CONFIG=http://192.168.99.100:3000?skip_verify=true
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  volumes_from:
    - drone-data

drone-data:
  container_name: drone-data
  image: busybox
  net: none
  command: /bin/sh
  volumes:
    - /var/lib/drone

gogs:
  container_name: gogs
  image: gogs/gogs
  ports:
    - "3000:3000"
    - "22022:22"
  volumes_from:
    - gogs-data

gogs-data:
  container_name: gogs-data
  image: busybox
  net: none
  command: /bin/sh
  volumes:
    - /data
```

## トラブルシューティング

### gogs でレポジトリ作成したのに drone からそのレポジトリ見えない

gogs のインストール時に間違ったアドレスでインストールし、drone からその間違ったアドレスでアクセス使用しているのが原因の可能性が高い。gogs コンテナのアドレスを変更する際も該当するので gogs のアドレス変更は出来るだけ避けるべき。

gogs 及び drone から間違ったアドレスを画面上から直接修正する方法が現在ないので手っ取り早くやるなら以下（この方法は当然プロダクション環境では使えないので注意！）

 - gogs コンテナの `/data/gogs/conf/app.ini` の間違ったアドレスを修正する
   - vim/nano はイメージ上には入ってないので vi か sed をつかってなおす
 - drone の data コンテナを捨てて再作成
 - drone コンテナを再起動
 - drone にログインしなおす

[^1]: homebrew を入れてる場合は `/usr/local/etc/dnsmasq.conf` になるがない場合は http://qiita.com/okitan/items/fbc4cf39d63eb7152049 を見ること。
[^2]: El Capitan を実行してる場合は rootless により直接 `/etc/resolv.conf` を編集出来ないので https://support.apple.com/kb/PH21615?viewlocale=ja_JP&locale=ja_JP に従って `127.0.0.1` を追加すること。