GCP無料枠で個人用Gitサーバ

# モチベーション
偉い人は言いました。 
> **常にソースコード管理システムを使用すること**
> 出典：[達人プログラマー](https:/amazon.co.jp/dp/427421933X)

ということで、プライベートな開発環境構築の第一歩として個人用のGitサーバを立てることにしました。
以下のような方針で進めていきます。

* クラウドインフラ利用
* Infrastructure as Code (IaC) の実現
* **無料(重要)**

Git立てるついでに無料でクラウドでIaCやろう！みたいな感じです。
具体的には、GCPの無料枠インスタンス上でGogsを立てつつdocker-composeで構成管理します。

# 1. GCPの無料枠でインスタンスを立てる
* [これから始めるGCP（GCE）　安全に無料枠を使い倒せ](https://qiita.com/Brutus/items/22dfd31a681b67837a74)

この記事の通りにやれば特に問題なくインスタンス作成からssh接続までいけました。感謝。 
インスタンス作成時に月額予測が$5.08と出てて首を捻ったけど、無料枠内の設定でも金額を表示しているみたい。
手順的に異なる点だけを列挙します。

#### OSはCentOS7を採用
一番利用経験があるから。特にこだわりはないです。

#### http/https用に80と443番ポートを開放
インスタンス作成時に

* HTTP トラフィックを許可する 
* HTTPS トラフィックを許可する

の2つにチェックを入れるだけでOK。もちろん後からルール追加も可能です。
(参考：[ファイアーウォール ルールの設定](https://qiita.com/Brutus/items/22dfd31a681b67837a74#%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%83%BC%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB-%E3%83%AB%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A))
#### rootパスワードを設定
不慮の事故でSSHが使えなくなったときの緊急策として、GCPのダッシュボードからコンソール接続するために設定しました。
他のリカバリ方法があるかもしれない。

# 2. docker-composeのインストール
先人がまとめてくださっています。バッチリ後追いしました。

* [CentOS7にDockerをインストールする](https://qiita.com/inakadegaebal/items/be9fecce813cebec5986)
* [Docker Composeのインストール方法(CentOS7.3)](https://qiita.com/uhooi/items/fb14d99d3323bd2eee9d)

バージョン指定はしていませんが、インストールされたバージョンは以下の通り。

* `Docker version 19.03.0, build aeac9490dc`
* `docker-compose version 1.18.0, build 8dd22a9`

# 3. Gogsのセットアップ

GitサーバにはGogsを採用しました。
軽量であることと、Go言語が勉強できればいいなと思ったことが選定理由です。

#### 事前準備
事前にswap領域を作っておきます。
OSデフォルトでswap領域が用意されておらず、これがないと`Cannot allocate memory for the buffer pool`と言われてMySqlのコンテナ起動に失敗しました。

*  [【Linux】スワップ領域の作成](https://qiita.com/azusanakano/items/96e7c490c285d9ec1b1a)

サイズは1024MBで作成。インスタンスのメモリが600MBとかなので、もう少し大きくても良かったかもしれません。

#### 起動
起動は`docker-compose up -d`で一発ドン。

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

services:
  gogs:
      container_name: gogs
      image: gogs/gogs:latest
      restart: always
      ports:
        - "80:3000"
        - "{インスタンスのsshポート}:22"
      environment:
        - RUN_CROND=true
      volumes:
        - /data
      depends_on:
        - gogs-db

  gogs-db:
      container_name: gogs-db
      image: mysql:5.7
      environment:
        - MYSQL_ALLOW_EMPTY_PASSWORD=false
        - MYSQL_ROOT_PASSWORD=gogs
        - MYSQL_DATABASE=gogs
      volumes:
        - /var/lib/mysql
```

これでインスタンスへブラウザからアクセスするとGogsのインストール設定画面が開くので、docker-composeを参考にしつつDB接続などを設定します。
アカウントを作成し、作成した非公開リポジトリに上記のdocker-composeをpushしてひとまず動作確認完了。

# 4. Gogsの設定追加
このままだとアカウントが作り放題だったり、gitのURLにインスタンスのIPが丸見えだったり、リポジトリのアドレスが`http://localhost(以下略`だったりとイケてないところが多いので、設定を追加します。

#### 設定ファイルをコンテナ外に
以下の構成で、設定ファイルを外出し。

```
infra/
 ├ docker-compose.yml
 ├ gogs/
    ├ Dockerfile
    └ app.ini
```
設定ファイルの元ネタはコンテナの中身から抜いてきました。

```shell:コンテナのファイルをホストへコピー
docker cp gogs:/data/gogs/conf/app.ini ./gogs/
```

#### 設定追加
Gogsにxxx.example.netのように適当なドメイン名からアクセスできるようにします。
アカウントの新規登録を無効にする設定も一緒に。

```ini:gogs/app.ini(抜粋)
DOMAIN                = xxx.example.net
ROOT_URL              = http://%(DOMAIN)s/
DISABLE_REGISTRATION  = true
```

gogsはDockerfileから起動するように変更します。

```yml:docker-compose.yml(抜粋)
services:
  gogs:
      container_name: gogs
      image: ./gogs

```

Dockerfileは設定ファイルをコピーしてイメージ起動するだけのかんたん設定。

```docker:gogs/Dockerfile
FROM gogs/gogs:latest
COPY app.ini /data/gogs/conf/app.ini
```

#### 動作確認
クライアントに名前解決の設定追加。

```text:/etc/hosts
{サーバのIPアドレス}  xxx.example.net
```

これで`http://xxx.example.net/`でGitにアクセスできるようになりました。めでたしめでたし。

# TODO
* Nginx(リバプロ)追加  
随時他のウェブサービスを追加したいので、Nginxを使って振り分け。
* DNS設定  
/etc/hostsを書くのは面倒なのでDNSにおまかせしたい。
* SSL化
* SSO化
* データの永続化  
docker-composeを初めて触ったので永続化の仕組みをさっぱり理解してません。
IaCにおけるデータの位置づけとかも含めて勉強して綺麗にしたいです。