探しても探しても良いものが見つからなかったので、alpine linuxベースのgitlab-ceを自作してみました

# はじめに
ここで紹介する自作のDockerイメージは個人的に使用するために作成しております。
基本的には問題なく動作するように頑張っておりますが、万が一トラブル等でデータが消えてしまっても責任は負えません。バックアップ等はしっかりとお願い致します。

alpine linuxベースのgitlabのニーズがあまり無さそうなので単純にやってみました、っていうだけになりそうですが、誰かの参考になれば幸いです。
（この頃はomnibusパッケージがあるのでわざわざソースからやる必要ないんですよねぇ）

ところで `alpine linux` 楽しすぎです。マイブームです。

## 経緯
もともと私はgitlab 6.3.0-preのソースから初代gitlabを立ち上げ、数カ月後に6.7.3にアップデートしただけで、ずっとそのバージョンで４年１ヶ月ほど使用していました。
アップデート時のbundle installトラブルに懲りて触らぬ神に祟りなし状態・・・
構築したはいいけども、アップデートってすんなり出来ないもんですね。

そんな状態もDockerで構築すれば全て解決、と言うことでgitlabコンテナイメージを探して歩きました。

最初は皆さんも使うであろうgitlab/gitlab-ceやsameersbn/gitlabをもちろん使うわけですが、

* なんかイメージサイズでけえ
* なんだか痒いところに手が届かん
* omnibusパッケージはイマイチ慣れないのでソースからのビルドがいい
* なんかDockerfileや中のソースがごちゃごちゃしてて訳がわからん
* 大体のイメージが`This image has vulnerabilities`で`critical`がいっぱい出てる
* gitlabはバージョンアップしてるけどdockerイメージがバージョンアップするの遅い

たくさんの不満が噴出してきました。
そこで、もういっそのこと自作することにしました。

## 方針
折角なので以下を頑張る。

* alpine linux(edge)ベース
* gitlabのソースからビルド（alpine linux用にomnibusパッケージがない）
* イメージサイズを小さく抑える
* セキュアなイメージにする(no vulnerabilities)
* gitlabのアップデートに遅れを取らないようにする
* なるべくシンプルでわかりやすくする
* コンテナイメージ入れ替えによるgitlabのアップデートを簡単に出来る様にする
* **無停止アップデートは諦めて**確実なアップデートを出来る様にする

##　構成
今回の構成コンポーネントは以下。

1. gitlab (postgresql) 
2. gitlab-shell
3. gitaly
4. gitlab-workhorse
5. nginx

ここにないredisとpostgresqlは別コンテナとして起動させる。
gitlab-pageとかは別途！まずは本体をどうにか動かす！

最終的にopenssh-serverもインストールしなかったですが使用用途がいまいちわからないので、どなたかご存知でしたら教えて頂きたいです。
git clone git@localhost:root/test.gitなどの使い方は想定できるのですがgitユーザのログインを禁止にしてたり、パスワードが・・・っていう問題がある気がしています。
ここで、ユーザ毎に登録するSSHキーが機能するってことでしょうか・・・
レポジトリのパスについても例で表示されている通りだとパスがずれててNot foundになる、などなんかうまく動いていない感。
それならいっそSSHアクセスをやめて「Only HTTP(S)」の方が良い気がします。

## ソース
gitlab-ce on alpine linux
https://github.com/toshi0123/gitlab-ce

## コンテナイメージ　[![Docker Repository on Quay](https://quay.io/repository/toshi0123/gitlab-ce/status "Docker Repository on Quay")](https://quay.io/repository/toshi0123/gitlab-ce)
https://quay.io/repository/toshi0123/gitlab-ce

![repo.png](https://qiita-image-store.s3.amazonaws.com/0/204453/bfb7478c-97a9-d1a9-61e5-8625ac23040f.png)

300MB前後に抑えれました！あとセキュリティスキャンも問題なく通ってます！

## 起動方法

※docker-composeは今回パス
最初にdocker networkを作成します。

```shell=
docker network create gitlab-network
```

redisを立ち上げます. (今回は自分のredisイメージを使っています)
library/redisなどの他のコンテナイメージでも動作します。  

```shell=
docker run --name gitlab-redis \
  -d \
  --hostname gitlab-redis \
  --log-opt max-size=10m \
  --log-opt max-file=4 \
  -v $PWD/redis:/data \
  --network gitlab-network \
  quay.io/toshi0123/redis:latest
```

postgresqlを立ち上げます。（Rails 4はPostgresql 10をサポートしていないので、9.6を使います）
こちらもlibrary/postgres:9.6.6-alpineなどのほかのコンテナイメージでもいいです。

```shell=
docker run --name gitlab-postgres \
  -d \
  --hostname gitlab-postgres \
  -e 'POSTGRES_USER=gitlab' \
  -e 'POSTGRES_PASSWORD=gitlabpassword' \
  -e 'POSTGRES_DB=gitlabhq_production' \
  -e 'DB_EXTENSION=pg_trgm' \
  --log-opt max-size=10m \
  --log-opt max-file=4 \
  -v $PWD/postgres:/var/lib/postgresql/data:rw \
  --network gitlab-network \
  quay.io/toshi0123/postgres:9.6.10-r0
```

最後にgitlabを起動させます。（HTTPSで立ち上げたい場合は、起動前にHTTPSセクションをご確認下さい）
※SECRETSは３２文字以上のランダムな文字列を設定して下さい。

```shell=
docker run --name gitlab \
  -d \
  -p 80:80 \
  -p 443:443 \
  --hostname gitlab \
  -e 'GITLAB_SECRETS_DB_KEY_BASE=please-modify-by-yourself' \
  -e 'GITLAB_SECRETS_SECRET_KEY_BASE=please-modify-by-yourself' \
  -e 'GITLAB_SECRETS_OTP_KEY_BASE=please-modify-by-yourself' \
  --log-opt max-size=10m \
  --log-opt max-file=4 \
  -v $PWD/gitlab/etc:/etc/gitlab:rw \
  -v $PWD/gitlab/data:/home/git/data:rw \
  -v $PWD/gitlab/log:/var/log:rw \
  --network gitlab-network \
  quay.io/toshi0123/gitlab-ce:latest
```

gitlabが起動するのを待ちます。  

```
$ docker logs gitlab -f
...
The GitLab Unicorn web server with pid 132 is running.
The GitLab Sidekiq job dispatcher with pid 230 is running.
The GitLab Workhorse with pid 170 is running.
Gitaly with pid 178 is running.
GitLab and all its components are up and running.
+ /usr/sbin/crond -L /var/log/crond.log
+ set +x
```

起動後、ブラウザからhttp://127.0.0.1 にアクセスします。
初回アクセス時にパスワード変更が要求されます。変更後、アカウント名「root」でパスワードは先ほど変更済みのパスワードで管理者ログインが出来ます。

全データとコンフィグファイル、ログファイルは、`$PWD/redis`、`$PWD/postgres`、`$PWD/gitlab`ディレクトリに格納されています。
**これらのデータは消えない様にして下さい。**

## 設定について
### 環境変数

| 変数名 | 例 | 説明 |
| --------- | ------ | ----------- |
| DB_HOST | `gitlab-postgres` | Postgresqlホスト名(default: `gitlab-postgres`) |
| DB_PORT | `5432` | Postgresqlポート(default: `5432`) |
| DB_NAME | `gitlabhq_production` | Gitlab DB名(default: `gitlabhq_production`) |
| DB_USER | `gitlab` | Gitlab DBユーザ名(default: `gitlab`) |
| DB_PASS | `gitlabpassword` | Gitlab DBユーザパスワード(default: `gitlabpassword`) |
| REDIS_HOST | `gitlab-redis` | Redisサーバ名(default: `gitlab-redis`) |
| REDIS_PORT | `6379` | Redisサーバポート(default: `6379`) |
| GITLAB_SECRETS_DB_KEY_BASE | `very-long-random-string` | 暗号キー(default: `default`) |
| GITLAB_SECRETS_SECRET_KEY_BASE | `very-long-random-string` | 暗号キー(default: `default`) |
| GITLAB_SECRETS_OTP_KEY_BASE | `very-long-random-string` | 暗号キー(default: `default`) |
| GITLAB_HTTPS | `false` | HTTPSを使用するか(default: `false`) |

### HTTPS

初回起動時に`GITLAB_HTTPS`フラグが有効です。
`GITLAB_HTTPS`を`false`で起動し`true`に変更したい場合は、自身で$PWD/gitlab/etc/配下のコンフィグファイルを変更して下さい。
ssl用nginxのコンフィグファイルは/home/git/gitlab/lib/support/nginx/gitlab-sslにあります。
手動で変更した場合は今後gitlabのアップデートする際のために`cp -pf /home/git/gitlab/lib/support/nginx/gitlab-ssl /etc/gitlab/example/gitlab.conf.example`を実施して下さい。

HTTPSにする際はサーバ証明書が必要です。
gitlabコンテナを起動する前に`$PWD/gitlab/etc`にサーバ証明書を格納して下さい。

```
$ mkdir -p ./gitlab/etc/
$ cp -pf private.key ./gitlab/etc/gitlab.key
$ cp -pf public.crt ./gitlab/etc/gitlab.crt
```

## アップデート方法

アップデートする際はバックアップをして下さい。

```
$ docker exec -it gitlab sh
# cd /home/git/gitlab
# sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```

バックアップ後はコンテナを停止し、新しいコンテナイメージで起動すると自動的にDBマイグレーションが実施されます。

### アップデート時トラブル対処方法

検証時に発生したトラブルについて簡単にまとめておきます。

#### v10.1系 → v10.2系 database.yml.postgresqlの記述変更
database.yml.postgresqlの記載がちょっとだけ変更になっているため、エラーとなり起動に失敗します。

```
patching file /home/git/data/config/database.yml
Hunk #1 FAILED at 9.
Hunk #2 FAILED at 23.
Hunk #3 FAILED at 33.
Hunk #4 FAILED at 48.
4 out of 4 hunks FAILED -- saving rejects to file /home/git/data/config/database.yml.rej
--- database.yml.example
+++ database.yml.example
@@ -9,4 +9,3 @@
-  # username: git
-  # password:
-  # host: localhost
-  # port: 5432
+  username: git
+  password: "secure password"
+  host: localhost
@@ -23,2 +22,2 @@
-  password:
-  # host: localhost
+  password: "secure password"
+  host: localhost
@@ -33,4 +32,4 @@
-  pool: 5
-  username: postgres
-  password:
-  # host: localhost
+  pool: 10
+  username: git
+  password: "secure password"
+  host: localhost
@@ -48 +47 @@
-  # host: localhost
+  host: localhost
```

このときは、まず`$PWD/gitlab/etc/database.yml`の記載が正しいかを確認してください。
正しいことが確認できればexampleファイルを削除することで該当部分のチェックをスキップ出来ます。

```
$ rm -f ./gitlab/etc/example/database.yml.example
$ docker start gitlab
```

とすると今回エラーの出たdatabase.ymlの部分は通過し、起動できます。

### Postgresql 10を使用する場合
10.0から10.1にアップデートする際にMigration 20170830131015が失敗します。
https://gitlab.com/gitlab-org/gitlab-ce/issues/38222

初回起動のタイミングで10.2系から使用する場合は問題なさそうですが、Rails4がPostgresql 10をサポートしてないので、9.6系を使用した方が良さそうです。

## 苦労した点
### パッケージ不足
とりあえず実行！
あ、パッケージ足りない！
パッケージ追加！
とりあえず実行！
・・・
を繰り返しました。
alpine linuxはパッケージも細分化されてて嬉しいです。(皮肉では決してありません。)
### bundle installエラー
やっぱりどうしてもbundle installには悩まされるんですね。
gpgmeというパッケージが全くインストール出来ず心が折れかけました。
### busybox envバグ
busyboxのenvでは`-u`オプションが使用できずにエラーが起こります。
envの含まれるcoreutilsパッケージをインストールして回避しました。
### busybox kill機能不足
busyboxのkillコマンドでは`--`の記述が出来ないため、gitlabのinitスクリプトでエラーが出ていました。
細かいところで機能不足があります。（busyboxで軽量化してるのでしょうがないですが）
今回はgitlabのinitスクリプト側を修正しました。
### busybox pkill問題
-uオプションがないため、procpsを追加しましたが、なぜか機能しない。
PATHの設定上、busyboxさんのpkillが動作してしまいます。

```
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```

busyboxのリンクは`/usr/bin`に存在するのですが、procpsは`/bin`に入ってしまう。
このため、手動でbusyboxのリンクを削除→`/usr/bin`にprocpsのリンクを作成、と言う感じで回避しました。

### ssh経由でのgitアクセス断念
adduserでアカウントのログインを無効にしてるのに、どうやってsshでpushできるんだろうか。
色々と試した結果、sshを断念しました。
repositoriesへのパスの問題もありつつイマイチピンと来ていないところ。

### busybox patch不満
`diff -U0`の出力をそのまま使用できないと言う謎の制限があり、個人的には不満です。
前後1行を有効にすると少しでも違うとダメですし、柔軟ではなかったので、別途patchパッケージをインストールしました。

# 最後に
長々となってしまいました。ここまで読んで頂きありがとうございました。
今後もgitlabの愛用していきたいので最新機能を使いこなしていきたいです。