CIが通らないときの原因はRunner？GitLab設定でチェックすべき8項目

GitLab CI/CD を使っていて、次のようなトラブルに遭遇したことはありませんか？

- `.gitlab-ci.yml` は合ってるのにジョブが実行されない
- Runner は登録されているのに動かない
- Docker ビルド中に謎のエラーで落ちる

こういった問題の多くは、「GitLab CI/CD（定義ファイル）」と「GitLab Runner（実行環境）」の**密接な依存関係**を正しく理解していないことが原因です。

本記事では、**GitLab CI/CDとGitLab Runnerの連携ポイント（依存関係）** を中心に、設定のしくみと注意点を詳しく解説します。

## そもそも GitLab CI/CD と Runner の関係とは？

- `.gitlab-ci.yml`: **ジョブの定義（何をどう動かすか）**
- GitLab Runner: **ジョブの実行者（実際に動かす人）**

CI/CD の流れはこうです

1. GitLab が `.gitlab-ci.yml` に基づいてジョブを作成
2. ジョブを実行できる Runner を検索
3. Runner が条件に合えばジョブを取得して実行

つまり、**CI/CD は Runner が動かないと全く実行されない**のです。

## GitLab CI/CD と Runner の依存ポイントまとめ

以下が、CI/CD 定義と Runner が密に連動する設定ポイントです。

### ① Executor と `image:` の依存

| Executor   | `.gitlab-ci.yml`での影響              |
| ---------- | ------------------------------------- |
| Docker     | `image:` を指定しないとジョブ実行不可 |
| Shell      | `image:` を書いても無視される         |
| Kubernetes | Pod 作成に必要な `image:` が必須      |

```yaml
# Docker Executor の例
image: node:20

build:
  script:
    - npm install
```

**Docker Executor を使っているのに image がない**と、ジョブが即失敗します。

---

### ② タグの一致がないと Runner が選ばれない

Runner にはタグが付けられており、`.gitlab-ci.yml` 側で **同じタグを指定しないとジョブを引き受けません**。

```toml
# config.toml (Runner 側)
[runners]
  tags = ["docker", "nodejs"]
```

```yaml
# .gitlab-ci.yml
build:
  tags:
    - docker
  script:
    - npm run build
```

タグが合わなければ GitLab 側で「このジョブを実行できる Runner が見つからない」となります。

---

### ③ ボリュームの依存：キャッシュやアーティファクトが壊れる原因

Runner（特に Docker Executor）では `config.toml` でマウントするボリュームが指定されています。

```toml
# Docker Executor の config.toml の例
volumes = ["/cache", "/builds"]
```

`.gitlab-ci.yml` で指定した `cache:` や `artifacts:` のパスがここにないと、**キャッシュが効かない or 失敗**します。

---

### ④ DinD（Docker in Docker）には privileged が必要

Docker 内で Docker コマンドを実行する（いわゆる DinD）には、Runner 側で以下の設定が必要です。

```toml
# Runner の config.toml
privileged = true
```

```yaml
# .gitlab-ci.yml
image: docker:24
services:
  - docker:dind

build:
  script:
    - docker build -t myapp .
```

`privileged = false` のままだと、`docker build` で「cannot connect to Docker daemon」系のエラーになります。

---

### ⑤ 環境変数の注入：Runner の実行ユーザーによって変わる

GitLab で設定した CI/CD Variables は、Runner 側に**環境変数として注入**されますが、Runner の実行ユーザーや Executor によって正しく反映されないこともあります。

- 環境変数は `protected` や `masked` で制限可能
- Shell Executor の場合、`sudo` 実行中は変数が参照できないこともある

→ **変数が見つからない系のトラブル**はこの依存を疑ってください。

---

### ⑥ Runner のバージョンと GitLab サーバの互換性

GitLab Runner は GitLab 本体と密接に連携するため、**バージョンが大きく乖離しているとエラーや非対応機能が発生**することがあります。

特に新しい `.gitlab-ci.yml` 構文や機能（`rules:`、`needs:` など）は **Runner 側のバージョンも対応している必要**があります。

**推奨**：Runner は GitLab 本体と同じバージョン系列か、少なくとも ±1バージョン以内に保つ。

---

### ⑦ ファイルシステムパーミッションと Runner 実行ユーザーの権限

Docker Executor や Shell Executor では、Runner の実行ユーザーがファイルを書き込めないことがあります。

- Docker Executor: volume マウント時にホストとコンテナの UID/GID 不一致で書き込みエラーになる
- Shell Executor: `/home/gitlab-runner` に書き込めずジョブが失敗することがある

```yaml
script:
  - echo "test" > /restricted/output.txt  # パーミッションエラーになる可能性
```

対策：

- `docker run` 時に `--user` オプションを調整
- ホスト側で `/builds`, `/cache` のパーミッション確認
- `.gitlab-ci.yml` の冒頭で `chown`, `chmod` を明示的に行う

---

### ⑧ GIT_CLONE_PATH の有効化には Runner の設定が必要

`.gitlab-ci.yml` で `GIT_CLONE_PATH` を指定すると、クローン先のディレクトリを変更できますが、これは GitLab Runner 側の設定に依存しています。

- Runner の `config.toml` で `runners.custom_build_dir.enabled = true` に設定されていない場合、**`GIT_CLONE_PATH` は無視されます**
- デフォルトではこの設定は無効（`false`）になっているため、**明示的に有効化する必要があります**

```toml
[runners]
  custom_build_dir = true
```

| 条件                                       | `GIT_CLONE_PATH` の動作         |
| ------------------------------------------ | ------------------------------- |
| `runners.custom_build_dir.enabled = true`  | 有効（指定パスに clone される） |
| `runners.custom_build_dir.enabled = false` | 無効（Runner が無視する）       |

**使いどころ**：

- ジョブごとにクローン先を整理したい場合
- キャッシュパスやマウントパスを制御したいとき

---

## ☑️ チェックリスト：CI/CD と Runner の依存で詰まりやすいポイント

| チェック項目                                   | よくあるミス                                 |
| ---------------------------------------------- | -------------------------------------------- |
| Executor に合った `image:` を指定しているか    | Shell Executor なのに image 指定             |
| Runner タグとジョブのタグが一致しているか      | タグ未指定で Runner が反応しない             |
| Docker in Docker で `privileged` が true か    | Docker ビルドが失敗する                      |
| キャッシュパスとボリューム設定が一致しているか | キャッシュが壊れる                           |
| 環境変数が渡っているか                         | `$SECRET_KEY` が空になる                     |
| Runner バージョンが GitLab 本体と近いか        | 新機能が使えない・ジョブが失敗する           |
| ファイルの書き込み権限が正しく設定されているか | 権限エラーでファイル操作に失敗する           |
| `GIT_CLONE_PATH`に`custom_build_dir`が有効か   | `.gitlab-ci.yml`でパスを変えても反映されない |

## まとめ

GitLab CI/CD は `.gitlab-ci.yml` を書くだけでは不十分で、**GitLab Runner の設定とペアで考える**必要があります。  
Runner の設定（`config.toml`）やタグ、Executor、privileged フラグなど、**CI/CD 側と密に連動する項目**を理解しておくと、トラブルを未然に防ぎ、より信頼性の高い CI/CD を構築できます。