# 部署指南:GitHub Pages 面板 + 本地探针 面向的场景:**面板托管在 GitHub Pages(公开、免运维),探测跑在自己家里/内网的机器上**。 ``` ┌─────────────────────────────┐ ┌──────────────────────────────────┐ │ GitHub Pages(静态托管) │ HTTPS │ 你自己的机器(内网/家用) │ │ ├─ index.html + assets/ │◄────────┤ ├─ Node 探针:持续探测 │ │ └─ 读 status.json 取配置 │ fetch │ ├─ /admin 管理端(2FA 保护) │ │ │ │ └─ 写 local.monitors.json │ └─────────────────────────────┘ └──────────────────────────────────┘ ``` 为什么面板不能直接读本地探针?因为 GitHub Pages 是**纯静态**的,只能读仓库里的文件。 数据要上去,靠两件事:**跨域读接口**(本指南的方式)或 **Actions 提交快照**(下文备选方案)。 --- ## 一、先决条件 | 条件 | 说明 | | --- | --- | | **本地探针有 HTTPS 地址** | Pages 强制 HTTPS,浏览器禁止 HTTPS 页面请求 HTTP(混合内容)。用你自己的隧道 / 反代给探针套一层 HTTPS | | Node.js ≥ 18| 零依赖,只需 Node 自带模块 | | 一个 GitHub 仓库 | 公开仓库即可(Pages 免费额度对公开仓库无限) | > ⚠️ **混合内容是硬限制**:即使 CORS 配对了,只要探针是 `http://`,浏览器仍会直接拦截请求,控制台只留一行 `Mixed Content ... was blocked`。这一条没有绕过办法。 --- ## 二、本地:跑探针 ```bash git clone <你的仓库> cd shiroko-monitor # 私有配置(可选):真实地址、API Key 等敏感信息放这里,不入库 node prober/node/index.js ```
想用私有配置文件? `local.monitors.json` 是可选的,不存在也能跑(会直接用 `public/monitors.json`)。 需要拆分敏感信息时自建即可,结构如下: ```jsonc // local.monitors.json(已在 .gitignore 中) { "_comment": "按 id 覆盖 public/monitors.json 的同名条目,或覆盖 settings", "settings": { "uptimeRobot": { "enabled": true, "apiKey": "ur...", "pollIntervalSec": 300 }, "probeScope": "all" }, "monitors": [ { "id": "example-com", "url": "https://real-internal-host.example" } ] } ```
启动后确认: ``` 面板:http://localhost:8787/ 管理后台: http://localhost:8787/admin ``` ### 让探针能被外部访问 默认它**只监听 `127.0.0.1`**。要让隧道/反代连进来,在 `local.monitors.json` 里打开: ```jsonc { "settings": { "admin": { "allowRemote": true } // 监听 0.0.0.0 } } ``` > 打开后同一端口上的公开面板也会对外可达(只读,但目标名称/地址/可用率会暴露)。 > 如果不希望这样,请在隧道那层按路径只放行 `/admin` 与 `/api/admin/*`。 ### 绑定管理端 2FA(必做) 管理端能改配置、发通知,必须先绑定两步验证: ```bash # 首次绑定需要这个口令(只从环境变量读,不写进任何文件) export SHIROKO_ADMIN_SETUP_KEY='换成一串足够长的随机口令' node prober/node/index.js ``` 然后打开 `https://你的隧道地址/admin`,按提示扫码绑定、保存恢复码。 --- ## 三、页面:部署到 GitHub Pages ### 1. 开启 Pages 仓库 **Settings → Pages → Build and deployment → Source** 选 **GitHub Actions**。 ### 2. 推送代码 ```bash git push ``` ### 3. 填两处配置(关键) 打开 `https://你的隧道地址/admin`,在「口径与范围」区块填: | 字段 | 填什么 | | --- | --- | | **面板上的管理入口链接** | `https://你的隧道地址/admin` —— Pages 面板页脚会出现「管理」按钮跳过去 | | **跨域数据源地址** | `https://你的隧道地址`(不带路径)—— 面板从这里取数据 | | **允许跨域读取的页面地址** | `https://你的用户名.github.io` —— 必须是完整来源,含协议 | 填完立刻生效。回本地仓库提交改动: ```bash git add public/monitors.json && git commit -m "chore: 配置跨域数据源" && git push ``` > 配置写在 `local.monitors.json`(私有层)的话,Pages 上的面板读不到 —— > 它只能读仓库里的 `public/monitors.json`。所以上面的两步(管理界面填 → 提交仓库)都要做。 ### 4. 验证 打开 `https://你的用户名.github.io/<仓库名>/`,检查: - 页脚数据源显示「**远程探针(跨域)**」—— 说明跨域打通了 - 表格有数据且状态正常 - 页脚有「管理」按钮,点击能跳到管理端 - **页面上没有「刷新」按钮** —— 跨域模式下该接口必然被`refreshLocalOnly` 挡下,隐藏比给一个失败的按钮好 --- ## 四、安全要点 | 事项 | 说明 | | --- | --- | | **管理端 2FA 必须绑定** | TOTP(Google Authenticator 等)+ 10 枚一次性恢复码 | | **恢复码离线保存** | 只在绑定时显示一次,用掉一枚少一枚 | | **跨域白名单不要图省事写 `*`** | 代码里不存在 `*` 分支,写了也不生效。必须写完整来源,如 `https://you.github.io` | | **管理端永不放行跨域** | `/admin` 与 `/api/admin/*` 不带任何 `Access-Control-*` 头,外部页面既读不到也改不了 | | **会话** | 30 分钟无操作失效,最长 2 小时;进程重启全部失效 | | **登录限流** | 同一 IP 连续 5 次失败后指数退避锁定 | | **API Key** | 放 `local.monitors.json` 或环境变量,**绝不要写进 `public/monitors.json`**(会随Pages 公开) | --- ## 五、备选:不用跨域,改用 Actions 提交快照 如果不想暴露探针的 HTTPS 地址,可以让数据「流」到 Pages 而不是「拉」: ```yaml # .github/workflows/monitor.yml(示意) on: schedule: [{ cron: '*/5 * * * *' }] workflow_dispatch: jobs: probe: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: node prober/node/index.js --once --config=public/monitors.json - run: | git config user.name github-actions[bot] git config user.email 41898282+github-actions[bot]@users.noreply.github.com git add public/status.json git diff --staged --quiet || git commit -m "chore: status" && git push ``` 面板用 `?source=static` 读仓库里的 `status.json`。 **取舍**:探测跑在 GitHub Runner 上(不是你的机器),延迟 ≤5 分钟,且**没有通知、维护窗口、事件、2FA 管理端**。适合纯展示需求。 --- ## 六、常见问题 **面板一直转圈 / 报错** 浏览器控制台看具体报错: - `Mixed Content ... was blocked` → 探针地址不是 HTTPS,回第一节 - `blocked by CORS policy` → 「允许跨域读取的页面地址」没填对,或与实际访问地址不一致(含 `www`、端口、大小写) - `Failed to fetch` 且数据源显示「浏览器直连」 → 面板拿不到数据,退到了兜底模式 **页脚没有「管理」按钮** 「面板上的管理入口链接」为空(默认就是空的,为了不在公网暴露管理面位置)。 **跨域下没有刷新按钮** 这是预期行为。跨域模式下 `/api/refresh` 会被服务端的 `refreshLocalOnly` 挡下(对端是代理地址而非私网),前端自动隐藏了这个按钮。 **改了配置但面板没变** 管理端写的是 `local.monitors.json`(私有层)。如果那部分设置需要 Pages 上的面板看到,得手动同步到 `public/monitors.json` 并提交。 **本机开发时前端跨域被拒** 默认白名单放行 `localhost` / `127.0.0.1`且**忽略端口**,所以 `localhost:5173` 这类能直接用。若你在局域网 IP 上跑前端,需把那个地址显式加进白名单。