# Git からのデプロイ

> GitHub、GitLab、Gitea、Forgejo のリポジトリをサーバーに接続し、プッシュ、リリース、タグのたびに自動でデプロイします。保護されたパス、再起動、CI チェック、ワンクリックのロールバックにも対応しています。

Portal の **Git Deploy** タブでは、サーバーを **GitHub**、**GitLab**、**Gitea**、**Forgejo** のリポジトリに接続できます。ファイルは自動的にサーバーへコピーされます。プッシュするたび、リリースを公開するたび、タグをプッシュするたび、またはボタンを押したときに行われます。ご希望であれば、デプロイの前にサーバーを正しく停止し、完了後に再び起動します。

要するに、コードをプッシュすれば、数秒後にはサーバーで動いています。SFTP でのアップロードも、ファイルマネージャーでの ZIP ファイルの展開も、再起動のし忘れもなくなります。

## このページで学べること

- リポジトリを接続する方法（Daki Git Deploy GitHub アプリ、またはアクセストークンを使用）
- デプロイが実行されるタイミングと、自分でデプロイを開始する方法
- 保護されたパスで、ワールド、データベース、`.env` ファイルを安全に保つ方法
- 再起動、デプロイ履歴、ロールバック、リポジトリ内のステータスの仕組み
- チームメンバーに適切な権限を与える方法

---

## 対象者

- **Discord ボットや Node.js、Python、Java アプリの開発者**で、コードがすでに GitHub や GitLab にある方。
- **Minecraft ネットワークやゲームサーバーのチーム**で、プラグイン、設定、データパックをリポジトリで管理し、変更を追跡可能な形で反映したい方。
- **チーム:** 複数の人がリポジトリで作業し、サーバーは常に最新の状態になります。誰がデプロイできるかは、サブユーザーの権限で正確に決められます。
- **リリースベースのプロジェクト:** 作業中のものすべてではなく、公開されたバージョン（例: リリースで完成した `.jar`）だけがサーバーに反映されます。

---

## 始める前に

- Portal で **Git Deploy** タブが表示されるサーバー。サーバーのナビゲーションの **Essentials** の下にあり、デフォルトでは **Files** のすぐ後に表示されます。
- GitHub（github.com）、GitLab（gitlab.com または自分のインスタンス。`group/subgroup/project` のようなサブグループを含む）、Gitea、Forgejo（Codeberg や自分のインスタンスなど）のリポジトリ。公開リポジトリと非公開リポジトリのどちらも使えます。

> **メモ:** Daki は、サーバーの種類（egg）ごとに、このタブを表示するかどうかを決めています。**Git Deploy** が表示されない場合は、お使いのサーバーの種類では有効になっていません。

> **情報:** このガイドでは、Git Deploy タブの英語のラベルを使っています。このタブは 19 言語で利用でき、Portal で選んだ言語に従います。ボタンの位置はどの言語でも同じです。

---

## GitHub でクイックスタート（推奨）

最も手早い方法は、**Daki Git Deploy**（Daki Hosting の公式 GitHub アプリ）で接続することです。GitHub にサインインして、使用するリポジトリを選びます。**トークンも Webhook も不要です。**

**ステップ 1: Git Deploy タブを開く**

Portal でサーバーを開き、**Git Deploy** タブに移動します。**Git service** で **GitHub** を選びます。

**ステップ 2: GitHub に接続する**

**GitHub access** のボックスで **Connect with GitHub** をクリックします。GitHub にサインインして、アプリを承認してください。

初めての場合、GitHub はそのままアプリがアクセスできるリポジトリの選択（**All repositories** または選んだリポジトリのみ）へ進みます。手順は 2 回ではなく 1 回で済みます。その後 Portal に戻ると、**GitHub access** のボックスに **Connected via Daki Git Deploy as** と GitHub のユーザー名が表示されます。**Webhook** のボックスには、設定が不要であることが示されます。プッシュとリリースは、アプリを通じて自動的に届きます。

**ステップ 3: リポジトリとブランチを選ぶ**

**Choose from my repositories** をクリックして、リポジトリを選びます — または Web の URL やクローン用の URL を貼り付けるか、パスを入力します。**Load branches** をクリックして、デプロイするブランチを選びます。ブランチを空欄のままにすると、リポジトリのデフォルトブランチが使われます。

**ステップ 4: デプロイのタイミングと方法を選ぶ**

**When to deploy** で、モード（例: **Every push**）を選びます。続けて、ターゲットフォルダー、[保護されたパス](#protected-paths)、[再起動の動作](#restart-behavior) を設定します。

**ステップ 5: 保存する**

画面下のバーで **Save settings** をクリックします。これで完了です。タブの上部に **Automatic deploys on** と表示され、次のプッシュから自動的にデプロイされます。すぐにデプロイするには、右上の **Deploy now** をクリックします。

- **別のリポジトリを許可する:** **Choose repositories on GitHub** をクリックすると、GitHub でリポジトリの選択画面が再び開きます。そこで、**Daki Git Deploy** がアクセスできるリポジトリを選べます。
- **接続を解除する:** **Disconnect** をクリックします。その後、サーバーは非公開リポジトリからデプロイしなくなります。

> **ヒント:** 何かを更新する必要はありません。デプロイのたびに、Portal が GitHub から新しい短期間有効なキー（1 時間有効）を取得します。このキーはサーバーのリポジトリ 1 つにのみ使われます。これはバックグラウンドで行われます。

---

## アクセストークンでクイックスタート

**GitLab**、**Gitea**、**Forgejo** の場合、また GitHub でもお好みであれば、個人アクセストークンを保存します。公開リポジトリはトークンがなくても使えます。

**ステップ 1: Git サービスを選ぶ**

サーバーを開き、**Git Deploy** で **Git service** を選びます。自分の GitLab インスタンス、Gitea、Forgejo の場合は、サーバーの URL を入力します（例: `https://codeberg.org` や `https://git.example.com`）。gitlab.com の場合は空欄のままにします。

**ステップ 2: リポジトリを入力する**

リポジトリをパス（`owner/name`）で入力するか、Web の URL またはクローン用の URL を貼り付けます。**公開**リポジトリの場合は、これだけで十分です — トークンがないと、アクセスボックスに **No token – public repositories only** と表示されます。

**ステップ 3: 非公開リポジトリ用のトークンを保存する**

GitHub の場合は、まず **GitHub access** ボックスの **Use an own access token instead** をクリックします。次に Git プロバイダーでトークンを作成します。Portal の **Create a token on …** のリンクから、正しいページに直接移動できます。その後、**Personal access token** の下に保存します。Portal はトークンをすぐに確認します。必要な権限については、[トークンの権限](#token-permissions) を参照してください。

**ステップ 4: 設定を選んで保存する**

デプロイのタイミング、ターゲットフォルダー、保護されたパス、再起動の動作を選び、**Save settings** をクリックします。

**ステップ 5: Webhook を追加する**

**Webhook** のボックスに **Payload URL** と **Secret** が表示されます。それぞれにコピーボタンがあります。[Webhook を設定する](#set-up-the-webhook) の説明に従って、リポジトリに追加してください。ボックスの下の **Last delivery** で、Webhook が届いているかどうかを確認できます。

**ステップ 6: 自動デプロイをオンにする**

**Automatic deploys active** をオンにします。

### トークンの権限

| プロバイダー | トークンの種類 | デプロイに必要な権限 | リポジトリ内のステータスに必要な追加権限 |
| :--- | :--- | :--- | :--- |
| GitHub | 細かく設定できるトークン（このリポジトリのみ） | *Contents: Read-only*（**Wait for CI checks** の場合は *Actions: Read-only* も） | *Commit statuses* と *Deployments*: *Read and write* |
| GitLab | 個人、プロジェクト、またはグループのアクセストークン | `read_api` と `read_repository` | `read_api` の代わりに `api`、ロールは Developer |
| Gitea / Forgejo | Settings → Applications | `repository: Read`、`user: Read` | `repository: Read and Write` |

ステータスへの書き込み権限だけが不足している場合でも、サーバーへのデプロイは行われます。デプロイログに注記が表示されます。

### Webhook を設定する

**GitHub**

リポジトリで **Settings → Webhooks → Add webhook** に移動します:

1. Portal の **Payload URL** と **Secret** を貼り付けます。
2. Content type を `application/json` に設定します。
3. イベントでは **Just the push event** を選びます。リリースモードでは代わりに **Releases** を選びます。

**GitLab**

プロジェクトで **Settings → Webhooks** に移動します:

1. **Payload URL** を URL に、**Secret** を **Secret token** に貼り付けます。
2. トリガーで **Push events** を選びます。タグモードでは **Tag push events**、リリースモードでは **Releases events** を選びます。

**Gitea / Forgejo**

リポジトリで **Settings → Webhooks → Add webhook** に移動し、Gitea または Forgejo を選びます:

1. **Payload URL** を貼り付け、content type を `application/json` に設定して、**Secret** を入力します。
2. **Push events** を選びます。リリースモードでは **Custom events → Release** を選びます。

> **ヒント:** Git プロバイダーから Portal に接続できない場合（例: Gitea インスタンスがご自宅のネットワーク内で動いている場合）は、代わりに **Also check … for updates** の下で間隔を選んでください（例: **Also check Gitea for updates**）。最初のチェックで、現在の状態が一度デプロイされます。

---

## デプロイが実行されるタイミング

**When to deploy** で、次の 4 つのモードから 1 つを選びます:

| モード | デプロイされるもの |
| :--- | :--- |
| **Manual** | 誰かが **Deploy now** をクリックしたときのみ。 |
| **Every push** | 選んだブランチへのすべてのプッシュ。 |
| **Releases** | リリースが公開されたときのみ。リリースの **source code**（ソースコード）または **release file**（リリースファイル。例: `*.jar`）のいずれかをデプロイします。必要に応じて固定の名前（例: `server.jar`）で保存でき、`.zip` の場合は必要に応じて展開されます。プレリリースは含めることも、除外することもできます。 |
| **Tags** | パターンに一致するタグがプッシュされたとき（例: `v*`）。 |

### トリガー

- **Webhook:** Git プロバイダーが変更をすぐに通知し、数秒以内にデプロイが開始されます。GitHub アプリを使う場合は、自分で Webhook を設定しなくても自動的に行われます。
- **更新チェック（ポーリング）:** 任意です。Git プロバイダーから Portal に接続できない場合に使います。5 分から 1 日までの間隔を選べます。
- **Deploy now:** いつでも、ボタンのクリックで実行できます。リリースモードでは、特定のリリースを選べます。
- **プッシュをスキップ:** コミットメッセージに `[skip deploy]` を入れると、そのプッシュはデプロイされません。`[deploy skip]` と `[no deploy]` も使えます。

### CI チェックを待つ

**Wait for CI checks** をオンにすると（**Every push** モードのみ）、コミットの CI が成功してからデプロイされます。GitHub Actions、GitLab CI、Gitea/Forgejo Actions に対応しています。CI が失敗した場合、デプロイはスキップされます。

---

## すべての設定の説明

| セクション | 設定 | 内容 |
| :--- | :--- | :--- |
| リポジトリ | **Git service** | GitHub、GitLab、Gitea、Forgejo のいずれか |
| リポジトリ | **Server URL** | 自分で運用するインスタンスの場合のみ。インターネットから到達可能である必要があります |
| リポジトリ | **Repository** | `owner/name` または URL。**Choose from my repositories** で一覧を表示 |
| リポジトリ | **Branch** | 空欄 = デフォルトブランチ。**Load branches** で一覧を表示 |
| デプロイのタイミング | **Manual** / **Every push** / **Releases** / **Tags** | [デプロイが実行されるタイミング](#when-a-deploy-runs) を参照 |
| デプロイのタイミング | **Wait for CI checks** | **Every push** の場合のみ |
| デプロイのタイミング | **Include pre-releases**、**What to deploy**（**Source code** / **Release file**）、**Save as**、**Extract .zip files instead of uploading them** | **Releases** の場合のみ |
| デプロイのタイミング | **Tag pattern** | **Tags** の場合のみ（例: `v*`）。空欄 = すべてのタグ |
| デプロイのタイミング | **Also check … for updates**（Git サービスの名前が付きます。例: **Also check GitHub for updates**） | ポーリング: **Never (webhook only)**、5/10/15/30 分、1/3/6/12/24 時間 |
| デプロイのタイミング | **Automatic deploys active** | オフにすると Webhook とポーリングが止まります。**Deploy now** は引き続き使えます |
| デプロイのタイミング | **Show deploys in the repository** | コミットのステータス。[リポジトリでのステータス](#status-in-your-repository) を参照 |
| ファイル | **Folder in the repository** | サブフォルダーのみデプロイします（例: `dist`）。空欄 = すべて |
| ファイル | **Target folder on the server** | ファイルの配置先。`/` = サーバーのメインフォルダー |
| ファイル | **Protected paths** | 1 行に 1 ルール。[保護されたパス](#protected-paths) を参照 |
| ファイル | **Remove files that were deleted from the repository** | 任意の後片付け。下記を参照 |
| 再起動 | **Restart if running** / **Always start** / **Do not restart** | [再起動の動作](#restart-behavior) を参照 |
| 再起動 | **If the server does not stop** | 即時強制終了、または 5 秒、10 秒（デフォルト: **Kill after 10 seconds**）、15 秒、30 秒、1 分、2 分、5 分後に強制終了 |

変更は **Save settings** をクリックしたあとにのみ反映されます。保存されていない変更がある間は、画面下のバーに **Discard** と **Save settings** が表示され、**Deploy now** はロックされます。

**Remove files that were deleted from the repository** は、以前のデプロイで書き込まれたファイルのみを削除します。保護されたパスや、ご自身で作成したファイルは削除されません。空のフォルダーはそのまま残ります。

---

## 保護されたパス

**Protected paths** に指定したファイルやフォルダーは、デプロイによって**決して上書きも削除もされません**。まだ存在しない場合は、一度だけ作成されます。ゲームのワールド、データベース、パスワードの保護に最適です。

ルールは 1 行に 1 つずつ、ターゲットフォルダーからの相対パスで書きます。空行と `#` で始まる行は無視されます。`*` は `/` をまたいで一致することはありません。

| ルール | 保護対象 |
| :--- | :--- |
| `world/` | `world` という名前のすべてのフォルダー（階層の深さを問わず） |
| `/world/` | ターゲットフォルダー直下の `world` のみ |
| `*.db` | `.db` で終わるすべてのファイル（場所を問わず） |
| `.env` | `.env` という名前のすべてのファイル（場所を問わず） |
| `/config.yml` | ターゲットフォルダー直下の `config.yml` のみ |
| `plugins/*/config.yml` | `plugins` の直下にあるすべてのサブフォルダー内の `config.yml` |

よくある例:

**Minecraft**

```

world/

world_nether/

world_the_end/

plugins/*/config.yml

whitelist.json

ops.json

banned-*.json

```

**Discord ボット / Node.js**

```

.env

*.db

*.sqlite

node_modules/

data/

```

**Python**

```

.env

*.db

venv/

```

---

## 再起動の動作

| オプション | 動作 |
| :--- | :--- |
| **Restart if running** | ファイルを書き込む前にサーバーを停止し、そのあとに再び起動します。停止中のサーバーは停止したままです。 |
| **Always start** | 上記と同様ですが、停止中のサーバーもデプロイ後に起動されます。 |
| **Do not restart** | サーバーを実行したままファイルを置き換えます。 |

**If the server does not stop:** 一部のプログラム（特に Node.js アプリ）は停止シグナルを無視します。その場合、選んだ時間（即時、5 秒から 5 分、デフォルトは **Kill after 10 seconds**）が経過した後にサーバーを強制終了し、デプロイが止まらないようにします。即時強制終了は最も速いものの、サーバーには保存する時間がありません。

> **メモ:** 安全策が 2 つあります。サーバーがまったく停止しない場合、**ファイルは一切変更されません**。サーバーを停止したあとにデプロイが失敗した場合、サーバーは**再び起動されます**。

---

## デプロイ中に行われること

1. トリガー（プッシュ、リリース、タグ、更新チェック、またはボタン）によって、デプロイが作成されます。
2. **Wait for CI checks** がオンの場合、CI が成功するまで待ちます（**Waiting**）。
3. **Portal** が Git プロバイダーからアーカイブをダウンロードします。認証情報が Portal の外に出ることも、サーバー上に残ることもありません。
4. アーカイブが準備されます。選んだフォルダーのみを対象とし、保護されたパスは除外され、シンボリックリンクなど安全でない内容は破棄されます。
5. 設定に応じて、サーバーが停止されます（必要に応じて、選んだ時間の後に強制終了されます）。
6. ファイルがターゲットフォルダーに書き込まれます。必要に応じて、削除されたファイルも削除されます。
7. 設定に応じて、サーバーが再び起動されます。
8. 結果と完全なログが履歴に表示されます。有効な場合は、コミットのステータスとしても表示されます。

デプロイには通常 **10〜40 秒**かかります。これに、サーバーの停止にかかる時間が加わります。

---

## 履歴、ログ、ロールバック

タブの下部にある **Deployments** の一覧には、すべてのデプロイがステータス、ブランチ、コミット（例: `main @ 75cd0a1`）、番号、トリガー、開始したユーザー、時刻、コミットメッセージとともに表示されます。タブの上部には、サーバーが最後にデプロイされた日時が表示されます。

| ステータス | 意味 |
| :--- | :--- |
| **Waiting** | CI チェックの完了を待っています |
| **Scheduled** | キューに入っており、まもなく開始されます |
| **Running** | デプロイ実行中です |
| **Deployed** | 正常に完了しました |
| **Failed** | 問題が発生しました。ログに詳細が表示されます |
| **Skipped** | デプロイされませんでした。例: CI が失敗した場合、またはコミットに `[skip deploy]` がある場合 |
| **Cancelled** | 開始前にキャンセルされました |

- **ログ:** すべてのデプロイにはライブログがあり、デプロイの実行中に更新されます。**Hide log** で閉じます。
- **ワンクリックでロールバック:** 以前のデプロイで **Deploy again** をクリックすると、その状態をもう一度反映します。
- **キャンセル:** 待機中またはスケジュール済みのデプロイはキャンセルできます。

複数のサーバーで同時にデプロイできますが、各サーバーで実行できるデプロイは 1 つだけです。新しいトリガーが、まだ待機中の古いデプロイを置き換えます。

---

## リポジトリでのステータス

**Show deploys in the repository** をオンにすると、コミットに **Daki Hosting / *サーバー名*** というステータスが表示されます。デプロイ実行中は黄色、完了後は緑のチェックマークまたは赤いバツ印になり、Git Deploy タブへのリンクが付きます。

- GitHub では、デプロイは **Deployments** にも表示され、環境名としてサーバー名が使われます。
- GitHub アプリを使う場合、ステータスは **Daki Git Deploy** によって書き込まれ、そのロゴが表示されます。ほかに設定は不要です。トークンを使う場合は、トークンのアカウントのアイコンが表示され、トークンに書き込み権限が必要です（[トークンの権限](#token-permissions) を参照）。
- サーバーごとにオフにできます。公開されるのはステータスとリンクだけです。ログやエラーの詳細は含まれません。

---

## チームとサブユーザーの権限

[サブユーザー](https://daki.cc/ja/wiki/guides/subusers) は、専用の権限グループ **Git Deploy** を持ちます:

| 権限 | 許可される内容 |
| :--- | :--- |
| **view** (`github.read`) | 設定、Webhook のアドレス、ログ付きの履歴を表示 |
| **deploy** (`github.deploy`) | **Deploy now**、**Deploy again**、デプロイのキャンセル |
| **change settings** (`github.update`) | リポジトリ、アクセス、Webhook、すべての設定の変更 |

サブユーザーは、初期状態では Git Deploy へのアクセス権を**持ちません**。どの権限を誰に与えるかは、ご自身で決めてください。サーバーの所有者は常にすべての操作を行えます。

---

## セキュリティ

- トークンとシークレットは**暗号化**されて保存され、ブラウザーに**送信されることは一切ありません**。
- GitHub アプリを使う場合、デプロイのためにご自身の長期間有効なトークンは一切使われません。デプロイのたびに短期間有効なキー（1 時間）が使われ、**サーバーのリポジトリにのみ**届きます。
- 接続できるリポジトリは、ご自身の GitHub アクセス権で決まります。ほかの人のリポジトリを、自分のサーバーに取り込むことはできません。
- Webhook は、サーバーごとに固有のシークレットで**署名**されます。シークレットが誤っている場合や、別のリポジトリ向けの配信は拒否されます。
- リポジトリを変更できるのは、トークンを保存した本人だけです。そのため、サブユーザーが所有者のトークンを使って、ほかの非公開リポジトリを読み込むことはできません。
- Git サービスまたはサーバー URL を変更して保存すると、保存されていたトークンは自動的に削除されます。
- 保護されたパスは決して上書きされず、**Remove files that were deleted from the repository** は Git Deploy 自身が書き込んだものだけを削除します。
- リポジトリに公開されるステータスには、ログやエラーの詳細は含まれません。

---

## 既知の制限

- サーバーごとに 1 つのリポジトリと 1 つのアクセス設定。
- 各サーバーで同時に実行できるデプロイは 1 つだけです。
- リポジトリでのステータスは、デプロイが実際に開始されてから表示されます。CI の待機中には表示されません。
- リリースファイルは `.zip` ファイルの場合のみ展開されます。`.tar.gz` はファイルとしてアップロードされます。
- **Remove files that were deleted from the repository** のあとも、空のフォルダーはそのまま残ります。
- リポジトリのシンボリックリンクはデプロイされません。
- GitLab にはプレリリースがありません。日付が未来のリリースは、プレリリースとして扱われます。
- GitLab: プロジェクトにアップロードされたリリースファイル（`/uploads/…`）は、非公開プロジェクトではトークンを使ってダウンロードできません。パッケージレジストリへのリンクは機能します。
- **Connect with GitHub** は GitHub でのみ利用できます。GitLab、Gitea、Forgejo はトークンを使います。

---

## よくある質問とトラブルシューティング

**トークンは定期的に更新する必要がありますか？**

GitHub アプリの場合は不要です。Portal がデプロイごとに新しいキーを自動的に取得します。ご自身のトークンは、Git プロバイダーで作成したときに設定した期間有効です。期限が切れたら、新しいトークンを保存してください。

**リポジトリがリストに表示されません（GitHub アプリ）**

**Choose repositories on GitHub** をクリックし、そのリポジトリにアプリがアクセスできるように許可してください。

**デプロイが Scheduled のままです**

少し待ってください。数分以上続く場合は、[サポートに連絡](https://daki.cc/ja/wiki/guides/support) してください。

**Webhook が届かない、または GitHub にエラー 401 と表示されます**

シークレットが一致していません。Portal でシークレットをコピーし、Webhook に入力し直してください。**New secret** をクリックすると新しいシークレットが作成されます。その場合は、Git プロバイダーでも変更してください。

**デプロイがスキップされたのはなぜですか？**

考えられる理由: CI チェックが失敗した、コミットメッセージに `[skip deploy]` が含まれている、または待機中のデプロイが新しいトリガーによって置き換えられた。理由はデプロイの行に表示されます。

**コミットにステータスが表示されません**

**Show deploys in the repository** をオンにする必要があります。トークンを使う場合は、トークンにも書き込み権限が必要です（[トークンの権限](#token-permissions) を参照）。理由はデプロイログに表示されます。

**デプロイが “The node rejected the request” で失敗します**

サーバーの種類で特定のファイルが許可されていないか、ディスクがいっぱいです。詳細はログに表示されます。

**自分の Gitea インスタンスの URL が拒否されます**

自分で運用するインスタンスは、インターネットから到達可能である必要があります。`192.168.x.x` のような家庭内ネットワークのアドレスは機能しません。

**ロールバックするにはどうすればよいですか？**

履歴で、戻したい以前のデプロイの **Deploy again** をクリックします。

**ゲームのワールドやデータベースが上書きされませんか？**

**Protected paths** に記載されていれば上書きされません（例: `world/` や `*.db`）。

**チームの誰がデプロイできますか？**

サーバーのサブユーザー設定の **Git Deploy** グループで **deploy** 権限を持つユーザーだけです。サーバーの所有者は常にすべての操作を行えます。

---

## 次のステップ

- [サブユーザー](https://daki.cc/ja/wiki/guides/subusers) — チームにアクセス権を与え、誰がデプロイできるかを決めます。
- [環境変数](https://daki.cc/ja/wiki/guides/environment-variables) — トークンやパスワードをリポジトリに含めないようにします。
- [起動設定](https://daki.cc/ja/wiki/guides/startup-settings) — デプロイしたコードが実行される起動コマンドを設定します。
- [バックアップ](https://daki.cc/ja/wiki/guides/backups) — サーバーの自動バックアップを Google Drive に保存します。

---
Source: https://daki.cc/ja/wiki/guides/git-deploy
