# 从 Git 部署站点

Source: https://support.kapsulehost.com/zh-cn/site-git-deploy

Git Deploy 将仓库与站点连接起来，这样每次推送到您选择的分支时，都会克隆代码、运行构建并发布结果。本指南将介绍初始连接、完成设置所需的两个仓库端步骤、如何查看部署历史，以及决定 Node.js 应用如何构建的 buildpack 检测机制。

## Git Deploy 的位置

打开**网站**，点击该站点，在站点左侧菜单中打开**环境**分组，然后选择 **Git 部署**。附近还有两个相关页面：

- **部署**，该站点的完整部署历史，同样位于**环境**分组中。
- **Buildpack**，检测到的构建策略，仅适用于 Node.js 站点，位于**应用**分组中。

Git Deploy 页面对自身的说明很直白：连接一个仓库，之后每次推送到您配置的分支都会触发一次构建和部署。

![KPanel 中某站点的 Git Deploy 页面，显示已连接的仓库](https://support.kapsulehost.com/help/screenshots/site-git-deploy.4716f1a9.webp)

## 连接仓库

1. 选择您的**提供商**：GitHub、GitLab 或 Bitbucket。
2. 输入**仓库 URL**。您需要使用 SSH 形式，例如 `git@github.com:user/repo.git`。
3. 设置要部署的**分支**。该字段默认值为 `main`。
4. 可选地设置**构建命令**，例如 `npm run build`。
5. 可选地设置**输出目录**，例如 `dist`、`public`，或对于已经构建完成的仓库使用 `.`。
6. 点击**连接仓库**。

如果您的仓库本身已可直接部署（对于纯 PHP 或静态站点来说这是常见情况），请将构建命令和输出目录留空。

### 高级脚本

展开**高级**会显示两个额外字段：

- **部署前脚本**，在构建之前运行。
- **部署后脚本**，在部署之后运行。

对于那些必须在新代码就位后才能执行的操作，请使用部署后钩子：清除应用程序缓存、运行数据库迁移、重启某个工作进程。

### 推送时自动部署

卡片底部的开关控制推送是否会触发部署。开启时，每次推送到已配置的分支都会触发一次部署。关闭时，只有在您通过**立即部署**手动触发时才会运行部署。

> **Tip:** 在代码冻结期或发生故障期间，应关闭自动部署，而不是断开仓库连接。断开连接会丢弃部署密钥和 webhook 密钥，之后您必须重新完成这两个仓库端步骤。

## 在您的仓库中完成设置

在 KPanel 中连接仓库只是三个步骤中的第一步。在首次部署运行之前，页面会显示一个横幅，内容为**完成设置：还需 2 个步骤**，其中包含您所需的全部信息。

### 第 2 步：添加部署密钥

KapsuleHost 需要对您的仓库拥有读取权限才能克隆代码。该横幅会显示一个公钥，并附带**复制密钥**按钮。

将其粘贴到您仓库的部署密钥设置中。对于 GitHub，该横幅提供了**添加到 GitHub** 快捷方式，可直接跳转到正确的设置页面。只读权限即可，请勿授予写入权限。

### 第 3 步：添加 Webhook

Webhook 用于告知 KapsuleHost 发生了一次推送。该横幅会提供三个值：

| 字段 | 值 |
|---|---|
| 载荷 URL | 一个以 `/api/git-deploy/webhook/` 结尾、并附加此站点 ID 的 URL |
| 密钥 | 一个自动生成的签名密钥，点击眼睛图标之前处于隐藏状态 |
| 内容类型 | `application/json` |

将每个值复制到您仓库的 webhook 设置中。对于 GitHub，有一个**将 webhook 添加到 GitHub**的快捷方式。请将内容类型设置为 JSON，而不是默认的表单编码格式，否则载荷将无法解析。

> **Warning:** 请像对待密码一样对待 webhook 密钥。任何获得该密钥以及载荷 URL 的人，都可以触发您站点的一次部署。这两个值仅会展示给已经拥有该站点管理权限的人，并且该密钥在您点击眼睛图标之前始终处于隐藏状态。

## 手动部署

在 Git Deploy 页面点击**立即部署**，即可在不推送提交的情况下构建并部署已配置分支的当前最新代码。无论自动部署是否开启，此功能都可以使用，这正是它在冻结期内成为合适工具的原因：推送会被忽略，但您仍然可以发布修复。

## 查看部署历史

打开**环境**，然后选择**部署**。该页面标题为**部署历史**，按时间从新到旧列出由 webhook 或手动触发的每一次部署。

每一行包含：

- 一个状态图标和简短的提交 SHA，分支以标签形式显示。
- 提交信息，如果没有可显示的提交信息，则显示**手动部署**。
- 作者、距今的时间、耗时，以及触发方式。
- 一个状态标签。

状态包括**待处理**、**构建中**、**部署中**、**成功**和**失败**。只要有任务正在进行中，页面就会每五秒自动刷新一次，并在表格下方显示**自动刷新中**的提示，因此您可以让页面保持打开状态，实时查看部署完成情况。

### 部署失败时

失败的行右侧会出现一个**错误**按钮。点击它即可在页面内联展开捕获到的错误输出，而无需离开当前页面。该输出就是构建过程本身产生的错误文本，因此通常会指明出错的文件或命令。

请按以下顺序排查：阅读错误信息，在本地复现相同的构建命令，修复问题，然后推送。如果构建在本地可以成功但在此处失败，差异几乎总是环境方面的问题，例如您机器上全局安装但未声明的依赖，或者某个文件存在于工作目录中但未提交。

## Buildpack 检测

在 Node.js 站点上，**应用**分组中的 **Buildpack** 页面会显示 KapsuleHost 决定如何构建您应用的方式。检测过程会扫描仓库根目录下的文件，并以第一个匹配项为准：

| 检测结果 | 触发条件 |
|---|---|
| 自定义 buildpack | 根目录下存在 `kapsule.config.yaml` 或 `kapsule.config.yml` |
| Dockerfile buildpack | 根目录下存在 `Dockerfile` |
| Node.js | `package.json` 中存在 `start`、`build` 或 `dev` 脚本 |
| Python | `requirements.txt` 或 `pyproject.toml` |
| PHP | `composer.json` |
| 静态 | 根目录下存在 `index.html` |

如果没有任何匹配项，页面会予以说明，并列出支持的触发条件。添加 `Dockerfile` 或 `kapsule.config.yaml` 即可显式接管构建过程。

### 运行构建

点击**运行构建**即可将其加入队列。构建进行期间，页面每三秒轮询一次，**最近的构建**表格会显示最近几次运行的开始时间、类型、状态、耗时以及生成的镜像引用。点击某一行可查看其日志尾部内容。

同一时间只能有一个构建在进行。如果在已有构建排队或运行时再次触发，系统会拒绝并提示**构建已在进行中**，这是刻意设计的：两个构建同时写入相同的输出，正是导致站点部署到一半的原因。

## 断开连接

点击**断开连接**并确认。确认提示会明确说明影响范围：Git 部署配置和部署密钥将被移除，您的站点文件不会受到影响。站点将继续提供上一次部署的内容。

之后请在您的仓库设置中删除部署密钥和 webhook，完成清理工作。即使不删除，它们也只会失效，但遗留的失效条目会让下一次审查更加困难。

## 故障排除

**推送没有触发任何操作。** 首先检查自动部署开关，然后检查您仓库中的 webhook 设置。大多数服务商会显示最近的投递记录及其响应代码，可以立即判断请求是否已从您的仓库发出。

**克隆失败。** 可能是部署密钥缺失、粘贴时带入了换行符，或添加到了错误的仓库。请使用**复制密钥**按钮重新复制，而不要手动选中文本。

**部署成功但站点没有变化。** 很可能是输出目录设置有误。如果您的构建将文件写入 `dist` 而输出目录却为空，那么构建出的文件将永远无法到达对外提供服务的根目录。

**所有内容都显示待处理且一直没有变化。** 该部署已被加入队列但从未被执行。请手动触发**立即部署**，并在部署页面查看是否有错误行。

## 接下来可以了解

- [为 Pull Request 预览部署](https://support.kapsulehost.com/zh-cn/site-preview) 在此设置基础上为每个 PR 添加一个专属 URL。
- [为站点存储应用密钥](https://support.kapsulehost.com/zh-cn/site-secrets)，了解您的构建和运行时所需的凭据。
- [站点活动日志](https://support.kapsulehost.com/zh-cn/site-activity-log) 记录在此处所做的配置更改。
