マイクラデータパック、リソースパック開発のCI/CD環境を構築 ~GitLab、GitLab-Runner編~

業務が忙しかったり、awsの資格を取っているうちに4か月が経ち、GitLabも今月で17が出そうですね。
ということで、GitLabとGitLab-Runnerを構築します。

## CI/CD環境構築記事まとめ
- [マイクラデータパック、リソースパック開発のCI/CD環境を構築 ~準備編~ ](https://qiita.com/kkbase515/items/eba4eebbf7a645caa7c8)
- マイクラデータパック、リソースパック開発のCI/CD環境を構築 ~GitLab、GitLab-Runner編~ 
- [マイクラデータパック、リソースパック開発のCI/CD環境を構築 ~GitLab-CI編~ ](https://qiita.com/kkbase515/items/3d1a02e107f160cdc0ab)
- マイクラデータパック、リソースパック開発のCI/CD環境を構築 ~SSL化編~ （準備中）

## GitLabインストール

インストール方法は[公式ドキュメント](https://gitlab-docs.creationline.com/ee/install/docker.html)を参考
基本コピペで十分。以下のようにマウント場所やURL、ポート等をお好みで編集する感じで十分

※ ただし、イメージタグはlatest以外のものにすること（場合によってはGitLabが起動しなくなるため、16.11.0のようにバージョンを指定すること）

```docker-compose.yml
version: '3.6'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:16.11.1-ce.0'
    container_name: gitlab
    restart: always
    hostname: 'gitlab.example.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.example.com'
    ports:
      - '80:80'
      - '443:443'
      - '10022:22'
    volumes:
      - '/data/config:/etc/gitlab'
      - '/data/logs:/var/log/gitlab'
      - '/data/data:/var/opt/gitlab'
    shm_size: '256m'
```

ファイルを作成したら、以下のコマンドでコンテナを起動しましょう。
```shell
docker-compose up -d
```

### rootユーザでのログイン

rootユーザのパスワードは24時間で自動削除されるため、コンテナ起動したらまずrootユーザでログインして管理者ユーザを作成するかパスワードを変更しましょう

rootユーザの初期パスワードは以下のコマンドで確認できます。

```shell
# コンテナ起動確認（gitlabコンテナがupでしたらコンテナが起動しています。さらに、その横の()内が"healty"になれば、gitlabアプリケーションが起動したということなので、ブラウザからアクセスできます）
docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS                    PORTS                                                                                                               NAMES
d66afa0086ac   gitlab/gitlab-ce:16.11.1-ce.0   "/assets/wrapper"        32 minutes ago   Up 11 minutes (healthy)   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:10022->22/tcp, :::10022->22/tcp   gitlab

# rootパスワードを確認
docker exec -it gitlab bash
cat /etc/gitlab/initial_root_password
> Lud9Vf/+gwtfGiRF1d57H4ahky/llXWX8vF3zFmN9wE=
```

※ kubernetesで構築した場合は、secretリソースで管理されるので、24時間経過しても消えることはないため、急がなくても問題なし。ただし、暗号化されているので、パスワードを確認する際は復号しましょう。

## GitLabにアクセス

ホストサーバのグローバルIPアドレス（113.xxx.xxx.xxxなど）もしくはホスト名などでアクセスできます。

アクセスすると以下のようなログイン画面が出ると思います。
ユーザ名は`root`、パスワードは先ほどのコマンドで出力された文字列でログインできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/fcd60fd6-b306-a2a4-5c80-fc9aeeedff53.png)

ログインすると以下の画面が表示されます。
プロジェクトを作成するとスクショのようにプロジェクト一蘭が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/9c948cbe-2399-3335-7921-f72ec85dac4a.png)


ここまで特に問題なければ、`http://<グローバルIPアドレス>/admin` で管理者画面に行き、想定通りのバージョンでGitLabが起動していることを確認しましょう（これ地味に大事です）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/62b808bd-7a6d-1536-7484-d1b81d9164fd.png)

## グループの作成（任意）

グループの作成はしなくても問題ないですが、管理が煩雑になるので作成することを推奨します。
`http://<グローバルIPアドレス>/dashboard/groups`にアクセスし、New Groupからグループ名を入力し、Visibility Levelはpublicで作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/49c863fa-a361-db37-b5aa-88a950507c2a.png)

グループ作成後、必要であればパーミッション等の設定をしておきましょう。


## プロジェクトの作成

グループを作成した場合は、グループにアクセスした状態で、New Projectのボタンをクリックしてプロジェクトを作成します。

プロジェクト名を入力し、Visibility Levelはprivateで作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/22dc4887-6858-efba-cd01-04beecd038d9.png)

こちらもグループと同様にプロジェクト作成後、必要であればパーミッション等の設定をしましょう。
この状態でクローン、コミット、プッシュが問題なくできるので、コード管理が行えると思います。

## GitLab-Runnerを起動

GitLabでCI/CDを行う場合は、GitLab-Runnerを利用します。GitLab-Runnerは簡単に言うと、ジョブを実行するものといった具合です。ジョブを実行するための方法やジョブの並列度など、色々設定があります。

まだGitLab-Runnerを起動していないので、`docker-compose.yml`にGitLab-Runnerの設定を記載して、`docker-compose up -d`します。
```docker-compose.yml
  gitlab-runner:
    image: gitlab/gitlab-runner:v16.11.0
    container_name: gitlab-runner
    restart: always
    volumes:
      - '/data/gitlab-runner/config:/etc/gitlab-runner'
      - '/var/run/docker.sock:/var/run/docker.sock' #実行タイプをdockerにする場合は追加してください
```

## GitLabのプロジェクトにRunnerを登録
ジョブを実行するためのランナーを登録していきます。
GitLab-Runnerには以下の3種類があります
> - Specific runners : 特定のプロジェクトで利用できる
> - Group runners: 特定グループ内で利用。グループ内のすべてのプロジェクトで共用できる
> - Shared runners: 全てのプロジェクトで利用できる

今回は、別のマイクラのマップに対してリソースパックを適用するといったケースが考えられるので、Specific Runnerを登録します。Group内でRunnerを共有しても問題ない場合は、オーバーヘッド的にGroup Runnerで作成してもよいです。

ランナー用のトークンをコピーします。
[先ほど作成したプロジェクト](#プロジェクトの作成)のサイドメニューにあるSetting > CI/CD にアクセスし、Runnerメニューを開いて、New Project Runner横の3点リーダーをクリックすると、トークンが出ますので、コピーしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/8f726b5f-7a8e-2176-6b92-f6620e3377c5.png)

GitLab-Runnerコンテナに入ってプロジェクトにGitLab-Runnerを登録します。
以下の通りにコマンドを打てば、docker環境下でジョブを実行するRunnerが登録されます。
```shell
docker exec -it gitlab-runner bash
gitlab-runner register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
> http://gitlab # コンテナ間通信のため、http://<コンテナ名>を設定でよい
Please enter the gitlab-ci token for this runner
> <先ほどコピーしたトークン> # Specific Runnerのトークンが望ましい。グループランナーも可
Please enter the gitlab-ci description for this runner
> <ランナーの名前> # 適当でいいです
Please enter the gitlab-ci tags for this runner (comma separated):
> <タグ名> # .gitlab-ci.yamlで特定のランナーを利用するように指定します （空欄可）
Enter optional maintenance note for the runner:
>  # メンテナンスノート（空欄可）
Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
> docker
Enter the default Docker image (for example, ruby:2.7):
> docker:24.0.5 # 使いたいイメージがあればそれを指定（私は適当にホストにインストールしているdockerイメージを指定しました）
```
無事に登録にできれば、`/data/gitlab-runner/config/config.toml`（コンテナ内では/etc/gitlab-runner/config.toml）が生成されていると思います。
また、トークンをコピーしたページに、ランナーがオンラインで表示されていると思います。

## config.toml編集

セキュリティグループのインバウンドで80ポートに自インスタンスのプライベートIPアドレスと自PCのグローバルIPのみ許可しているので、cloneURLをコンテナに設定して直接通信する必要があります。また、今回のGitLab-Runnerの設定では、GitLab-CIでジョブ実行する際にホスト内でコンテナを作成して処理を実行します。コンテナ間通信を行うためには、同じネットワーク上にコンテナが存在しなければならないので、`network_mode`もconfig.tomlに記載しておきましょう。

そのため、以下のようにconfig.tomlを編集します。
```toml
concurrent = 1
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "test"
  url = "http://gitlab"
  id = 1
  token = "NmKoCttzNUEr2QzbtqAk"
  token_obtained_at = 2024-03-24T07:57:32Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  clone_url = "http://gitlab" # gitlabコンテナと通信するように設定
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "docker:24.0.5"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    network_mode = "gitlab_default" # これも追加
    shm_size = 0
    network_mtu = 0
```

## テストジョブを実行

さて、ここまでの手順でGitLabとGitLab-Runnerを構築できたと思うので、GitLabとGitLab-Runnerの動作確認を行います。
作成したプロジェクトのルートディレクトリに`.gitlab-ci.yml`を作成します。
```.gitlab-ci.yml
echo-job:
  script: 
    - echo "Ahoy! This is Gitlab CI/CD!"
```

コミットすると、コミットIDの横にボタンが表示されるので、ジョブがうまく動作しているかを確認するために、以下の画像の通りにボタンをクリックして、ジョブのログが出力されているページにアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/6914d5a4-06f3-f6ea-7eaf-ed1efb7c1b6b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351883/b3af35ae-d015-18af-0637-d0f23897386b.png)

アクセスすると、以下のようなログが流れていると思います。
```shell
Running with gitlab-runner 16.10.0 (81ab07f6)
  on test NmKoCttz, system ID: r_1NYsKvzxWAe2
Preparing the "docker" executor
00:03
Using Docker executor with image docker:24.0.5 ...
Pulling docker image docker:24.0.5 ...
Using docker image sha256:7015f2c475d511a251955877c2862016a4042512ba625ed905e69202f87e1a21 for docker:24.0.5 with digest docker@sha256:3c6e4dca7a63c9a32a4e00da40461ce067f255987ccc9721cf18ffa087bcd1ef ...
Preparing environment
00:01
Running on runner-nmkocttz-project-1-concurrent-0 via 5b2648bf8019...
Getting source from Git repository
00:04
Fetching changes with git depth set to 20...
Reinitialized existing Git repository in /builds/minecraft/test-project/.git/
Checking out db1e8937 as detached HEAD (ref is main)...
Skipping Git submodules setup
Executing "step_script" stage of the job script
00:00
Using docker image sha256:7015f2c475d511a251955877c2862016a4042512ba625ed905e69202f87e1a21 for docker:24.0.5 with digest docker@sha256:3c6e4dca7a63c9a32a4e00da40461ce067f255987ccc9721cf18ffa087bcd1ef ...
$ echo "Ahoy! This is Gitlab CI/CD!"
Ahoy! This is Gitlab CI/CD!
Job succeeded
```
以下のことが確認できれば、テストジョブが正常に完了しているので、GitLabとGitLab-RunnerのCI/CD環境ができたといえます。
- gitlab-runnerのバージョンがdockerイメージと一致していること
- `Enter the default Docker image (for example, docker:24.0.5)`で設定したイメージが使われていること
- リポジトリがクローン出来ていること（`Checking out <コミットID> as detached HEAD (ref is main)...`が出力されていればOK）
- echoコマンドが実行できていること（`Ahoy! This is Gitlab CI/CD!`と出力されていればOK）
- ログの出力の最終行が`job succeeded`となっていること
- ジョブのステータスが緑色のチェックマーク（Passed）になっていること