(改訂版) Docker でオフィシャルな GitLab イメージと Redmine イメージのコンテナを連携させる

## はじめに

これは以前書いた [Docker でオフィシャルな GitLab イメージと Redmine イメージのコンテナを連携させる](http://qiita.com/nkenbou/items/41b8c855d9a349a9a016#gitlab-%E3%81%A8-redmine-%E3%82%92%E9%80%A3%E6%90%BA%E3%81%95%E3%81%9B%E3%81%A6%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%93%E3%81%A8) の改訂版です。以前の記事では GitLab と Redmine のイメージをハックしていましたが、**イメージに手を加えずに** 連携する方法を見つけたので改めて記事にしました。

### 対象となる読者

* Docker で GitLab や Redmine を運用したい人
* [オフィシャルな GitLab イメージ](https://hub.docker.com/r/gitlab/gitlab-ce/) を使いたい人
* [オフィシャルな Redmine イメージ](https://hub.docker.com/_/redmine/) を使いたい人
* 上記のイメージから作成したコンテナを連携させたい人

### この記事を読んだ後できるようになること

* GitLab の Issues タブが Redmine のプロジェクトにリンクされます。
* GitLab のコミットメッセージ内の issue 番号が Redmine チケットにリンクされます。
* Redmine のチケット連携機能がそのまま使えます。

### この記事を書いたときのバージョン

* GitLab イメージ: gitlab/gitlab-ce: 8.15.4-ce.1
* Redmine イメージ: redmine:3.3.2
* PostgreSQL イメージ: postgres:9.6.1 ※Redmine 用

### ソースコード (docker-compose.yml、Dockerfile など)

今回作った GitLab & Redmine 環境構築のためのファイル一式は GitHub に置いてあります。

https://github.com/nkenbou/gitlab-redmine

## GitLab と Redmine を連携させてできるようになること

当記事で取り扱っているのは私自身が実際に試した機能だけです。ここに書いたこと以外にも便利な機能があるかもしれません。

* GitLab の **Issues** タブが Redmine のプロジェクトにリンクされます。
* GitLab の **New issue** メニューが Redmine の新規チケット作成ページにリンクされます。
* Git のコミットメッセージに `refs #123` など (チケット番号だと判定させるためのキーワード (`refs` など) は変更できます。後述。) と書くと、GitLab のコミットログから Redmine の `#123` チケットへのリンクが作成されるようになります。
* Git のコミットメッセージから、Redmine チケットの各種ステータス (作業時間など) を操作することができるようになります。

当記事では GitLab、Redmine とも `test` をプロジェクト名として説明します。

## 基本的な設定

ここでは、連携に直接関係はないけど、知らないとこの記事の内容を試すときにつまずきそうな基本的な設定について説明します。

### Redmine ユーザーの設定

Redmine の **ログインID** と各ユーザーの開発マシンの git 設定 `user.name` は合わせておくとよいです。

開発マシンの `user.name` を設定する方法です。

```sh
$ git config --global user.name "nkenbou"
```

もし、別々にしたい場合は次のページで、ログから検出された git ユーザーと Redmine ユーザーを関連付けることができます。

![redmine-repository-user.png](https://qiita-image-store.s3.amazonaws.com/0/85728/e5db39d7-a565-f664-2476-dab26eeaf407.png)

### Redmine で最低限必要な設定項目

* チケットのステータス
* トラッカー
* ワークフロー
* 列挙項目
    * チケットの優先度
    * 作業分類 (時間管理)

## 連携のための設定

ここでは、GitLab、Redmine それぞれに `test` プロジェクトが作成されていることを前提として説明していきます。

### GitLab に連携用アカウントを作成する

GitLab にあるリポジトリを redmine コンテナでクローンするために、GitLab にクローン用アカウントを作成します。

ここでは次の内容でアカウントを作成しています。

* **Username:** `redmine`
* **Password:** `redmineredmine`

作成したアカウントは対象のプロジェクト (例. `test`) のメンバーに **Reporter** 権限で追加しておきます。

### Redmine 側の設定

#### リポジトリ (管理) の設定

![redmine-admin-repository.png](https://qiita-image-store.s3.amazonaws.com/0/85728/1beec76f-3735-f88c-6787-e96f6d2aebd4.png)

**設定のポイント:**

* **コミットを自動取得する**: on
* **参照用キーワード**: チケット番号だと判定させるためのキーワードの設定です。`*` を追加するとキーワードが不要になります (例. `#123`)。
* **異なるプロジェクトのチケットの参照/修正を許可**: on
* **コミット時に作業時間を記録する**: on
* **作業時間の作業分類**: 適宜

#### Git リポジトリのクローン

Docker ホストの `./git_repositories` (redmine コンテナでマウントしているディレクトリ) に GitLab で作成したプロジェクトのリポジトリ (例. `test`) を **ベアリポジトリ** としてクローンします。

```sh
$ cd /path/to/git_repositories
$ git clone --bare http://redmine:redmineredmine@localhost:10080/nkenbou/test.git
```

その後、`remote.origin.url` のホスト名を `localhost:10080` => `gitlab` に変更します。これは、redmine コンテナ内から gitlab コンテナへはホスト名 (サービス名) でアクセスする必要があるためです。

さらに、クローンしたリポジトリのオーナーをコンテナ内の redmine ユーザーにします。redmine ユーザーの UID、GID はそれぞれ `999` です。

```sh
$ cd test.git
$ git config --local remote.origin.url http://redmine:redmineredmine@gitlab/nkenbou/test.git
$ sudo chown -R 999:999 .
```

ここでは HTTP/HTTPS プロトコルを使って ID + Password 付きの URL でクローンする例を載せていますが、**クローン用アカウント** の SSH キーを作成してあらかじめ GitLab に登録しておけば SSH プロトコルでもクローンできます。その場合、SSH キーは Redmine コンテナにボリュームをマウントするなどして設定してください。

#### リポジトリ (プロジェクト) の設定

![redmine-project-repository.png](https://qiita-image-store.s3.amazonaws.com/0/85728/dce4a795-8da2-51c0-4cc5-ea7568fd0852.png)

**設定のポイント:**

* **バージョン管理システム**: Git
* **リポジトリのパス**: /var/redmine/git_repositories/*XXX*.git
    * クローン先のパスを指定します。
* その他の設定は適宜

### GitLab 側の設定

#### Redmine サービス (テンプレート) の設定

Admin 権限でログインし、**Service Templates** > **Redmine** と選択していき Redmine サービスのテンプレートを設定するページを開きます。

![gitlab-service-template-redmine.png](https://qiita-image-store.s3.amazonaws.com/0/85728/e68b3dd5-69e9-0074-dee1-261e230fd35b.png)

**設定のポイント:**

* **Active**: on
* **Trigger**: on
* **Project url**: http://localhost:10081/projects/:project_id
* **Issues url**: http://localhost:10081/issues/:id
* **New issue url**: http://localhost:10081/projects/:project_id/issues/new

**捕捉:**
* `localhost:10081` の部分は Redmine のホスト名です。実際の環境にあわせて置き換えてください。
* `:project_id` の部分は (自動的に置き換えられそうですが) 個々のプロジェクトで Redmine サービスの設定をする際に手動で置き換えることになります。
* `:id` はチケットの ID になります。連携時に自動的に置き換わります。

#### Redmine サービス (プロジェクト) を設定

Redmine と連携したいプロジェクトで **Services** > **Redmine** と選択していき Redmine サービスを設定するページを開きます。

![gitlab-service-redmine.png](https://qiita-image-store.s3.amazonaws.com/0/85728/968e623d-2e11-63ae-7e69-5190523c6ac7.png)


**設定のポイント:**

* **Project url** 、 **New issue url** の `:project_id` 部分を Redmine 側のプロジェクト名 (例. `test`) に置き換えます。

#### Webhooks の設定

Redmine と連携したいプロジェクトの **Webhooks** メニューから Webhooks の設定ページを開きます。

![gitlab-webhooks.png](https://qiita-image-store.s3.amazonaws.com/0/85728/ef7c1c85-bd4a-f5c5-67cc-16c36b9640b7.png)

**設定のポイント:**

* **URL**: http://redmine:3000/github_hook?project_id=XXX
    * ホスト名: Docker 内でコンテナ同士を接続するために自動的に設定されるホスト名 (例. `redmine`) を指定してください。docker-compose.yml を使用している場合はサービス名になります。
    * ポート: Redmine のコンテナ側のポート (例. `3000`) を指定してください。
    * project_id=*XXX*: *XXX* の部分には Redmine 側のプロジェクト名 (例. `test`) を指定してください。

#### 捕捉説明

GitLab へプッシュしたら Redmine の Git リポジトリでフェッチしないとリポジトリが更新されないのでチケットにも各種情報は反映されません。
GitLab へのプッシュ時に自動的にフェッチを行うために、[redmine_github_hook](https://github.com/koppen/redmine_github_hook) という Redmine のプラグインを使用しています。GitLab の Webhooks で設定した URL のパスが **/github_hook** になっていますが、これがそのプラグインの提供するサービスの API になります。

## 動作確認

これで、設定は完了です。

Redmine のチケット連携機能だけ動作確認を載せておきます。

### コミット (作業時間の記録)

例. `#1` チケットに作業時間 2h30m で登録するようにコミット。

```sh
$ cd /path/to/test
$ echo "#GitLab & Redmine" > README.md
$ git add README.md
$ git commit -m "#1 @2h30m add title"
$ git push
```

![redmine-set-worktime.png](https://qiita-image-store.s3.amazonaws.com/0/85728/92a3a5c2-0ca3-79f5-f46b-ce60e85740cd.png)

コミットメッセージによる作業時間の記録については次のサイトが詳しいです。

http://blog.redmine.jp/articles/new-feature-1_1/automatic-spent-time-logging/

## まとめ

以前書いた [記事](http://qiita.com/nkenbou/items/41b8c855d9a349a9a016#gitlab-%E3%81%A8-redmine-%E3%82%92%E9%80%A3%E6%90%BA%E3%81%95%E3%81%9B%E3%81%A6%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%93%E3%81%A8) では Docker イメージをハックしていましたが、それがなくなったのでシンプルに環境が構築できるようになりました。これで後顧の憂いなく安心して運用していけそうです。

### 参考文献

* [Redmine Service - GitLab Documentation](https://docs.gitlab.com/ce/project_services/redmine.html)
* [リポジトリ — Redmine Guide 日本語訳](http://redmine.jp/guide/RedmineRepositories/)
* [Redmine 1.1 新機能紹介: コミットメッセージによる作業時間の記録 | Redmine.JP Blog](http://blog.redmine.jp/articles/new-feature-1_1/automatic-spent-time-logging/)
* [SE奮闘記: RedmineとGitLabの連携。PushでチケットのStatusを変更](http://blog.dksg.jp/2015/05/redminegitlabpushstatus.html)
* [Github の変更を redmine が参照するリポジトリに自動反映したい | BmathLog](http://bmath.org/wordpress/?p=1513)