# Next.js 项目基于 GitHub Webhook 与宝塔面板的自动化部署流程文档

## I. 概述

本流程文档详细介绍了如何通过 GitHub 的 Webhook 功能与宝塔面板相结合，实现 Next.js 项目代码的自动化部署。当您向 GitHub 仓库提交代码后，服务器将自动拉取最新代码、安装依赖、构建项目并重启应用，从而实现持续集成与部署（CI/CD），极大地提升开发效率和部署的可靠性。

**核心理念：** 一次性配置宝塔面板的基础环境和网站，后续代码更新通过 GitHub Webhook 触发宝塔面板执行自动化部署脚本。

## II. 前提条件

在开始配置之前，请确保您已具备以下条件：

1.  **GitHub 账号**：并已拥有一个托管 Next.js 项目代码的仓库。
2.  **宝塔面板服务器**：一台已安装宝塔面板的 Linux 服务器。
3.  **已安装环境**：服务器上已通过宝塔面板的软件商店安装了 **Nginx (或 Apache)**、**Node.js (推荐 LTS 版本)** 和 **PM2 管理器**。
4.  **Git 环境**：服务器上已安装 Git（通常宝塔面板会自带或可通过软件商店安装）。
5.  **域名解析**：您的域名已正确解析到宝塔面板服务器的 IP 地址。

## III. 整体部署流程概览

以下是整个自动化部署流程的高层概览图：

\`\`\`mermaid
graph TD
    A[开发者 Push 代码到 GitHub 仓库] --> B(GitHub 仓库);
    B -- 代码更新 --> C{GitHub Webhook 触发};
    C -- Payload URL & Secret --> D[宝塔面板服务器];
    D -- 执行 deploy_webhook.php 脚本 --> E[自动部署脚本: <br/> git pull <br/> npm install <br/> npm run build <br/> pm2 restart];
    E --> F[Next.js 应用更新并重启];
    F --> G[用户通过域名访问最新网站];
\`\`\`

## IV. 各环节详细流程与配置

### A. 阶段一：开发者本地代码提交与推送

这是您日常开发的工作流程。

\`\`\`mermaid
graph TD
    A[开发者本地修改 Next.js 代码] --> B[git add];
    B --> C[git commit -m "更新了新功能"];
    C --> D[git push origin main];
    D --> E(代码推送到 GitHub 远程仓库);
\`\`\`

**操作说明：**
您在本地完成 Next.js 项目开发后，通过标准的 Git 命令将代码提交并推送到 GitHub 仓库的指定分支（例如 `main` 或 `master`）。

### B. 阶段二：宝塔面板服务器环境与网站配置（由您手动完成，一次性）

这是实现自动化部署的基础，需要您在宝塔面板上进行一次性设置。

1.  **登录宝塔面板。**

2.  **安装 Node.js 和 PM2 管理器：**
    *   在宝塔面板左侧菜单选择 `软件商店`。
    *   搜索并安装 `Node.js` (推荐安装 LTS 版本，例如 16.x, 18.x, 20.x)。
    *   搜索并安装 `PM2 管理器`。PM2 是 Node.js 应用程序的生产级进程管理器，能确保您的 Next.js 应用在服务器上持续运行，并在代码更新后平滑重启。

3.  **创建网站与域名：**
    *   在宝塔面板左侧菜单选择 `网站` -> `添加站点`。
    *   填写您的**域名**（根据截图推测，可能是 `touzhi.quwanzhi.com` 或您实际绑定的域名）。
    *   `FTP` 和 `数据库` 可以选择不创建（如果您的 Next.js 项目是纯前端或后端分离的）。
    *   `PHP 版本` 选择 `纯静态`。
    *   `网站目录`：根据截图，您的项目可能在 `/www/wwwroot/tongzhi`。**请确认并记住这个目录。** 稍后它将是您的 Git 仓库克隆和 `deploy_webhook.php` 脚本存放的目录。
    *   点击 `提交`。

4.  **配置 Nginx 反向代理 Next.js 应用：**
    Next.js 应用通常运行在 Node.js 服务器上，并通过 Nginx 进行反向代理实现外网访问。
    *   在宝塔面板 `网站` 列表中，找到您刚刚创建的网站，点击右侧的 `设置`。
    *   切换到 `配置文件` 选项卡。
    *   在 `server` 配置块中，添加以下 `location` 配置（请将 `3000` 替换为 Next.js 应用实际监听的端口）：
        \`\`\`nginx
        # Nginx 配置示例 (添加到 server 段内)
        location / {
            proxy_pass http://127.0.0.1:3000; # <--- 替换为 PM2 启动的 Next.js 应用监听的实际端口
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
            # 如果您的 Next.js 应用有特殊路由需求，可能需要添加其他配置
        }
        \`\`\`
    *   点击 `保存`。

5.  **使用 PM2 管理 Next.js 应用：**
    *   在宝塔面板左侧菜单选择 `PM2管理器`。
    *   点击 `添加项目`。
    *   `项目目录`：选择您的网站根目录（根据截图可能是 `/www/wwwroot/tongzhi`）。
    *   `启动文件`：填写 `node_modules/next/dist/bin/next`。
    *   `项目名称`：根据截图，您的 PM2 项目名称可能是 `tongzhi` (**请务必记住这个名称，稍后在 Webhook 脚本中会用到**)。
    *   `启动参数`：填写 `start -p 3000` (这里的 `3000` 是您的 Next.js 应用监听的端口，请与 Nginx 反向代理中的端口保持一致)。
    *   点击 `提交`。
    *   PM2 会自动启动您的 Next.js 应用。您可以点击 `日志` 查看应用启动情况。

6.  **配置 Git 部署：**
    宝塔面板内置的 Git 部署功能是接收 GitHub Webhook 通知并触发部署脚本的关键。
    *   在宝塔面板 `网站` 列表中，找到对应的网站，点击右侧的 `设置`。
    *   在网站设置窗口中，找到 `Git` 选项卡，点击进入。
    *   勾选 `启用Git部署`。
    *   `平台` 选择 `Github`。
    *   `项目地址`：填写您的 GitHub 仓库的 HTTPS 地址。例如：`https://github.com/fnvtk/wztouzhi.git`。
    *   `分支`：填写您希望自动部署的分支名称，通常是 `main` 或 `master`。
    *   `Token`：**设置一个随机且复杂的字符串作为密钥**，例如 `your_custom_deploy_secret_wztouzhi_bt`。请务必牢记这个密钥，稍后在 GitHub Webhook 配置和部署脚本中会用到。
    *   `项目部署目录`：宝塔会自动填写网站的根目录（例如 `/www/wwwroot/tongzhi`），请确保它是您项目代码实际要部署的路径。
    *   `部署类型`：选择 `拉取`。
    *   **重要：`部署完成后执行的命令`：这里暂时留空，您将在后续步骤中将我为您生成的脚本内容粘贴到此处。**
    *   **获取 WebHook 地址：** 配置完上述信息并点击 `保存` 后，宝塔面板会为您生成一个 `WebHook地址`。**复制这个 URL！**

### C. 阶段三：GitHub 仓库 Webhook 配置（由您手动完成，一次性）

这个配置将使得 GitHub 在您推送代码时通知宝塔面板。

\`\`\`mermaid
graph TD
    A[登录 GitHub 仓库] --> B[Settings];
    B --> C[Webhooks];
    C --> D[Add webhook];
    D --> E[填写 Payload URL];
    E --> F[设置 Secret];
    F --> G[选择 'Just the push event'];
    G --> H[Add webhook];
    H --> I(Webhook 配置完成);
\`\`\`

**操作说明：**
1.  **登录 GitHub**，进入您的 `wztouzhi` 项目仓库。
2.  点击仓库顶部的 `Settings`（设置）。
3.  在左侧导航栏中，点击 `Webhooks`。
4.  点击 `Add webhook`（添加 Webhook）。
5.  填写以下信息：
    *   **Payload URL**：粘贴您在宝塔面板 Git 部署设置中复制的 `WebHook地址`。
    *   **Content type**：选择 `application/json`。
    *   **Secret (可选，但强烈推荐)**：粘贴您在宝塔面板 Git 部署中设置的 `Token` (那个强密码)。
    *   **Which events would you like to trigger this webhook?**：选择 `Just the push event.`（仅推送事件）。
    *   `Active`：确保此选项被勾选。
6.  点击 `Add webhook` 完成添加。

### D. 阶段四：自动化部署脚本 `deploy_webhook.php` （由我提供，您粘贴到宝塔）

为了实现自动化构建和重启 Next.js 应用，我们需要一个 PHP 脚本来作为宝塔面板 Git 部署的"部署完成后执行的命令"。

我为您生成了以下 `deploy_webhook.php` 脚本。**您需要将此脚本的内容复制，并粘贴到宝塔面板网站设置中 Git 部署的"部署完成后执行的命令"文本框内。**

**脚本内容（已根据您的截图信息优化，请务必根据您的实际情况修改 `SECRET`）：**

\`\`\`php
<?php
// deploy_webhook.php
// GitHub Webhook for Next.js (React) project deployment on Baota Panel

// --- 安全配置 ---
// 建议在宝塔面板的环境变量中设置此密钥，或者从配置文件读取，避免直接硬编码
$SECRET = 'your_deploy_secret_wztouzhi_bt'; // **请替换为你在宝塔面板Git部署中设置的Token**
$PROJECT_ROOT = '/www/wwwroot/tongzhi'; // **已根据截图更新为 `/www/wwwroot/tongzhi`**
$LOG_FILE = $PROJECT_ROOT . '/deploy.log'; // 部署日志文件，用于记录部署过程

// --- 函数定义 ---
function log_message($message) {
    global $LOG_FILE;
    file_put_contents($LOG_FILE, date('[Y-m-d H:i:s]') . ' ' . $message . PHP_EOL, FILE_APPEND);
}

function verify_signature($payload, $signature, $secret) {
    $hash = 'sha1=' . hash_hmac('sha1', $payload, $secret);
    return hash_equals($signature, $hash);
}

// --- 请求处理 ---
log_message('Webhook triggered.');

// 获取 GitHub 请求头
$github_signature = $_SERVER['HTTP_X_HUB_SIGNATURE'] ?? '';
$github_event = $_SERVER['HTTP_X_GITHUB_EVENT'] ?? '';
$payload = file_get_contents('php://input');

// 验证 Secret
if (empty($github_signature) || !verify_signature($payload, $github_signature, $SECRET)) {
    log_message('Invalid signature. Aborting deployment.');
    http_response_code(401);
    die('Invalid signature');
}

log_message("GitHub Event: {$github_event}");

// 只处理 push 事件
if ($github_event === 'push') {
    log_message('Processing push event...');

    // 切换到项目根目录
    chdir($PROJECT_ROOT);
    log_message("Changed directory to: " . getcwd());

    // 执行 Git Pull
    log_message('Executing git pull...');
    $output = shell_exec('git pull 2>&1');
    log_message("Git Pull Output:\n" . $output);

    // 检查 Next.js 项目文件 (package.json)
    if (file_exists('package.json')) {
        log_message('Detected Next.js project. Installing dependencies and building...');

        // 安装 Node.js 依赖
        log_message('Executing npm install...');
        // 使用 --force 强制安装，避免因包版本冲突导致安装失败
        $output = shell_exec('npm install --force 2>&1');
        log_message("npm install Output:\n" . $output);

        // 构建 Next.js 项目
        log_message('Executing npm run build...');
        $output = shell_exec('npm run build 2>&1');
        log_message("npm run build Output:\n" . $output);

        // 重启 PM2 进程 (已根据截图更新应用名为 'tongzhi')
        $PM2_APP_NAME = 'tongzhi'; // **已根据截图更新：请替换为你在PM2管理器中设置的项目名称**
        log_message("Restarting PM2 process '{$PM2_APP_NAME}'...");
        $output = shell_exec("pm2 restart {$PM2_APP_NAME} 2>&1");
        log_message("PM2 Restart Output:\n" . $output);

    } else {
        log_message('No package.json found. Skipping Node.js specific commands.');
    }

    log_message('Deployment completed.');
    echo 'Deployment successful!';

} else {
    log_message('Event not supported. Only "push" events are processed.');
    echo 'Event not supported.';
}

http_response_code(200);
?>
\`\`\`

**脚本流程图：**

\`\`\`mermaid
graph TD
    A[GitHub Webhook 请求] --> B{deploy_webhook.php 接收};
    B -- 获取 Payload & Headers --> C{验证 Secret};
    C -- 签名不匹配 --> D[401 Unauthorised];
    C -- 签名匹配 --> E{事件类型为 Push?};
    E -- 否 --> F[跳过，不处理];
    E -- 是 --> G[切换到项目根目录];
    G --> H[执行 git pull];
    H --> I{检查 package.json 存在?};
    I -- 否 --> J[跳过 Node.js 命令];
    I -- 是 --> K[执行 npm install];
    K --> L[执行 npm run build];
    L --> M[执行 pm2 restart 应用名];
    M --> N(部署成功，返回 200 OK);
\`\`\`

### V. 自动化部署完成与验证

完成以上所有配置后，每次您向 GitHub 仓库的指定分支推送代码，就会自动触发部署流程：

1.  GitHub 发送 Webhook 请求到宝塔面板。
2.  宝塔面板接收请求并执行 `deploy_webhook.php` 脚本。
3.  脚本在服务器上拉取最新代码，安装/更新 Node.js 依赖，构建 Next.js 项目。
4.  PM2 自动重启您的 Next.js 应用。
5.  您的网站内容更新，并能通过您绑定的域名在外网访问到最新版本。

**验证方法：**
*   **查看 GitHub Webhook 记录：** 在 GitHub 仓库的 Webhook 设置页面，查看 `Recent Deliveries`，确保每次推送都有成功的绿色勾选。
*   **查看宝塔面板 Git 部署日志：** 在宝塔面板网站设置的 `Git` 选项卡中，通常会有部署日志，可以查看详细的执行情况。
*   **查看 `deploy.log` 文件：** 脚本会在项目根目录生成 `deploy.log` 文件，记录每次部署的详细信息，方便排查问题。
*   **访问您的网站：** 通过域名访问您的网站，确认内容是否已更新到最新。

### VI. 注意事项与优化

*   **安全性**：`Secret` 密钥是关键，请妥善保管，不要泄露。
*   **权限问题**：确保宝塔面板运行的用户（通常是 `www` 用户）对项目目录有足够的读写权限，以便 `git pull`、`npm install`、`npm run build` 等命令能够正常执行。
*   **依赖缓存**：在部署脚本中，`npm install` 会在每次部署时运行。如果您的项目依赖较多，可以考虑在 `Dockerfile` 中构建一个包含依赖的镜像，或者在服务器上对 `node_modules` 进行缓存处理，以加快部署速度（此文档以直接安装为默认）。
*   **错误处理**：脚本中已加入了日志记录，您可以通过查看 `deploy.log` 文件来排查部署失败的原因。
*   **生产模式**：确保您的 Next.js 应用在 `npm run build` 后是以生产模式构建的。
*   **持续学习**：自动化部署是一个持续优化的过程，您可以根据项目需求和服务器性能，不断调整部署脚本。
