workbuddy.xpcool.com/.workbuddy/memory/DEPLOY.md
夏犀麟 df607384ed docs: 记录 xpcool.com 主域名上线与移动端补完
- MEMORY.md 索引:xpcool.com 状态更新为已上线
- DEPLOY.md 站点清单:新增 xpcool.com / www.xpcool.com 一行
- 2026-09-13.md:追加上线记录与遗留项(gzip 待部署)
2026-09-13 23:04:33 +08:00

27 KiB
Raw Blame History

xpcool.com 生产环境 · 部署与运维手册

从 MEMORY.md 拆出2026-09-13存放服务器、容器、站点、安全加固与本机工具链坑位等细节。 MEMORY.md 只保留规则与索引。

生产部署(腾讯云 193.112.118.168SSH 22025/xxcoolDocker+宿主机 Nginx

  • 站点落点:前端静态 → /data/www/<域名>/nginx 配置 → /data/nginx/conf.d/<域名>.conf80→301→443 + 反代/静态);证书 → /data/nginx/ssl/<域名>/<域名>_bundle.crt|.key本地源:E:\CentOS\ssl\<域名>_nginx/2026-09-13 核对;证书只放 _bundle.crt+.key.csr/.pem 一并留存便于比对)。
  • service 后端容器:service.xpcool.com:new127.0.0.1:10100:10100,网络 xpcool-netenvGF_GCFG_ENV=prod + DB_DSN=mysql:service:xxx@tcp(xpcool-mysql:3306)/service?...必须带 mysql: 类型前缀+ JWT_SECRET;容器内必须有 manifest/config/config.yaml(基础配置),否则 GF 启动报「找不到 config」构建目录 /data/deploy/projects/service.xpcool.com/main + manifest/config + resourceDockerfile 用 COPY manifest/config 整体拷贝)。
  • DBxpcool-mysql 容器root 密码见该容器 env库名 service,种子执行顺序 003→004→004b→007服务器表结构旧必须先 003 加列;导入用 sudo sh -c 'docker exec -i xpcool-mysql mysql ... < file' 宿主机重定向)。
  • 权限映射admin_menu type=2 行的 path 必须匹配实际路由(现为 POST /api/service/admin/...,见 manifest/sql/007_menu_permissions_v3.sql
  • 文件下载站2026-09-03 上线,当晚迁移):file.xpcool.com = FileBrowser Quantum 容器 fbqgtstef/filebrowser:stable v1.5.5127.0.0.1:10881→80restart unless-stopped/data/share:/srv:ro 只读挂载,数据卷 /data/filebrowser-qconfig.yaml+database.db+tmp属主=镜像 uid1000+ nginx 反代。要点:初始凭据 admin/admin(首登后立即改密);配置走 config.yamlsources/cacheDir管理走网页 UIAPI 与原版不兼容(需用户建 long-live token/swagger 亦需);镜像默认非 root(uid1000);原版 filebrowser(容器 filebrowser/10880/db /data/filebrowser/database)已于 2026-09-01 归档、现已停用保留回滚Quantum v2.0 beta 权限模型改 per-source(view/download/modify/create/delete)。改密/建只读账号/临时分享(过期+密码+匿名)均在网页 UI。
  • SSH 凭据/密码不入库,需要时询问用户或查对话记忆;远程批量命令用 paramiko 脚本(%TEMP%\wb_deploy\ssh_exec.py,支持第 2 参数超时秒数docker build 用服务器端 nohup+日志轮询防超时。2026-09-11 密钥轮换后更新):当前登录 = 本地 ~/.ssh/xpcool_ed25519ed25519注释 xpcool-server-20260904xxcool@193.112.118.168:22025root 被拒;密码登录已禁);旧 CentOS.pem(RSA对应服务器公钥 skey-q6pq6jb3)已作废并从 authorized_keys 移除(因私钥误提交 Gitea 事件而轮换),服务器 authorized_keys 另存 2 把钥(mcp-server-manager@localxxcoolwork@gmail.com)为其他用途、保留不动;安全组按出口 IP 限放 22025本机出口 1.204.105.116 曾因未放行连不上80/443 可达);本机旧记录 ~/.ssh/id_ed25519 与 wb_deploy 脚本在当前设备不存在
  • 服务器安全加固2026-08-27 完成)firewalld 已启用(放行 22025/80/443/3000/2222cockpit/rpcbind 已停fail2ban 保护 sshd(port=22025, maxretry5/bantime1h);监控脚本 /usr/local/bin/server-monitor.sh + cron 每 10 分钟(调度在 xxcool 的 crontab*/10 * * * * sudo /usr/local/bin/server-monitor.sh;日志 /var/log/server-monitor.logBark 推送配 /etc/server-monitor.confBARK_URL告警去重终版2026-09-11:状态目录 /var/lib/server-monitor/ —— banned-ips.state(已提醒过的封禁 IP只增不减 → 同一 IP 永不重复提醒)、ssh-src-ips.state(已提醒过的登录来源 IP仅新 IP 首次登录才提醒)、ports.state(当前已告警的未登记端口,消失后清除)、ssh-brute.state(爆破告警状态机:attacking=本轮已提醒 / idle=已复位;攻击持续不刷屏,攻击停止静默复位,再犯视为新一波才重新提醒);完整审计仍在 fail2ban.log + journald 且已上报 admin 后台(脚本备份 server-monitor.sh.bak.20260911);另有安全日志上报器 /usr/local/bin/server-security-collector.shcron 每 5 分钟xxcool crontab→ POST 到 127.0.0.1:10100/api/service/open/security/log/report,配置 /etc/server-security.confINTERNAL_TOKEN、状态 /var/lib/server-security/last.tsdnf-automatic 每天 06:00 自动安全补丁SSH 密钥登录已部署(现用 ~/.ssh/xpcool_ed25519)、密码登录已禁。2026-09-11 加固:已关闭 X11Forwarding生效位置是 drop-in /etc/ssh/sshd_config.d/50-redhat.conf:17,主配置里那行是注释、改了无效;改前备份 .bak.20260911sshd -t 预检 + sshd -T 核对 + systemctl reload sshd 不断连nginx 遗留垃圾已清理(.code.xpcool.com.conf.swotool.xpcool.com.conf.download.0 → 移入 /data/nginx/_junk_backup_20260911/,未直接删、可回滚)。nginx 配置目录约定include /data/nginx/conf.d/*.conf;,故 conf.d 下非 .conf 后缀文件不会被加载。遗留待办lighthouse 账号(腾讯云自带 uid1000NOPASSWD ALL是否锁定待用户决策。:① 腾讯云安全组未放行 3000/2222/8081Gitea 走 nginx 反代 80/443② 改 sshd 前必须先 sshd -t 预检+备份(曾因脏行导致 SSH 断开);③ EPEL 源需腾讯云镜像(mirrors.cloud.tencent.com/epel)且 baseurl 必须手动写全;④ CentOS9 的 fail2ban 在 EPEL。2026-09-04 新坑)腾讯云改带宽若切计费模式会触发实例冷重启,重启后 firewalld 自定义端口规则曾丢失致 SSH 22025 失联80/443 正常——firewall-cmd 放行务必带 --permanent,且实例冷重启后要复查 22025 放行。另:带宽 3M→5M 已升级2026-09-04实测 619KB/s 满速)。2026-09-11 溯源新坑)本机出口 IP 1.204.105.116 曾于 09-03 23:00 被自己的 fail2ban 封禁、09-04 23:00 才解封——这正是当时「SSH 22025 超时」的真因当时误判为安全组未放行绕了远路。SSH 突然不通时,排查顺序应为:先 fail2ban-client status sshd + grep Ban /var/log/fail2ban.log,再怀疑安全组2026-09-11 体检结论)服务器未发现被入侵迹象UID0 仅 root、无空密码账号、无异常 SUID/后门/劫持、无特权容器、系统目录近 30 天无改动;外网暴露面实测仅 22025/80/4433000/2222/8081 等均被安全组挡住firewalld 虽放行 3000/2222 但安全组是第二道闸)。
  • 本地 pnpm 修复2026-08-27 升级为 wrapper 方案):根因=本环境 MSYS 路径转换故障,把 /c/... 参数转成 E:\c\...(多 E:\c\ 前缀)致 corepack shim 与 node 都找不到 pnpm.js。已建持久 wrapper~/.workbuddy/binaries/node/bin/pnpm(内容:export NODE_OPTIONS=--experimental-sqlite; exec "<托管node.exe>" "C:/Users/ybtdevxxl/.workbuddy/binaries/node/workspace/node_modules/pnpm/bin/pnpm.cjs" "$@",关键=给 node 传 Windows 风格路径 C:/... 规避 MSYS 转换)。提交/构建前需 PATH="~/.workbuddy/binaries/node/bin:$PATH" 前置pre-commit 钩子(lefthook oxlint/oxfmt/eslint/stylelint/checkType)即可正常运行;否则钩子崩 → 只能 --no-verify。已验证 pnpm 11.16.0 + pnpm exec oxlint 1.79.0。

日常同步习惯(建议)

  • 每次工作结束:在各改动项目 git add + commit,本工作空间同样提交(规则/日志变化时)。只 commit、不要 push2026-09-01 用户明确推送由用户自行完成AI 无需代为 push避免凭据交互失败
  • 验证分工2026-09-01 用户明确)AI 能做的验证(类型检查、构建、单元/二进制测试、自动化冒烟)照做;AI 不方便验证的部分(真实浏览器交互体验、视觉效果、下载弹窗等)直接交给用户手动验证,不要反复折腾自动化工具。
  • 换设备开工前:先 git pull 各仓库,保证规则与记录最新。

本机 Windows/PowerShell 工具链坑位2026-09-10 实测,写脚本必看)

  • PowerShell 工具不回显 stdoutexit code 正常但看不到输出;必须把结果 Out-File 落盘,再用 Read 读取。Bash 里调 powershell.exe 会被安全策略拒绝。
  • [byte] -shl 8 会溢出归零(结果仍是 byte 宽度)。字节拼 16 位整数必须先 [int] 转换,否则高位丢失(剪贴板/协议解析类代码的高频坑)。
  • 给 .ps1 加 BOM 绝不能用 Get-Content -Raw + Out-File:本机默认按 GBK 解码 UTF-8 文件,中文会被永久破坏且不可逆。正确做法是字节级前置 EF BB BF[System.IO.File]::WriteAllBytes)。
  • PATH 被裁剪:脚本里直接写 ping / netsh 会报"无法识别",须用 $env:SystemRoot\System32\xxx.exe 绝对路径;且不要写 & $exe args 2>$null | Out-String(会报"无法在管道中间运行文档"),改用 $out = & $exe args@($out) -join ' '
  • PowerShell 变量名不区分大小写$R 与循环变量 $r 是同一个变量,会导致集合被静默覆盖。
  • 后台监听的进程可能杀不掉Stop-Process / taskkill 均无效),换端口重新起更省事。
  • 防火墙规则按可执行文件路径匹配:一批 node.exe 规则指向已不存在的路径(失效);目前 C:\Users\xxl\AppData\Roaming\nvm\v23.0.0\node.exe 有有效的 Public 档「TCP+UDP 任意端口」入站放行规则——需要做免提权的入站可达性测试时就用它监听。
  • 测入站不要用 pingWindows 默认拦 ICMPv6/ICMP 入站,必须用 TCP 端口测试。
  • 国内测速Cloudflare 端点不可用;用 Ookla 官方 CLIinstall.speedtest.net 可直连下载)。
  • 本机网络备注:家里的宽带是运营商级 NATCGNAT第 2 跳 100.64.0.1,无公网 IPv4但有公网 IPv6240e:338:263:3600::/64)。以太网被判定为 Public 网络档。
  • ssh.exe 执行多行脚本会踩转义坑2026-09-13 实测):把多行 here-string 直接当参数传给 ssh.exe,远程 bash 解析到 ( 等字符会报 syntax error near unexpected token '('而且报错前的行已经执行了,导致状态半途而废(证书只搬了一半)。可靠做法:本地写 .sh 文件(用 -replace "rn","n"强制 LF +WriteAllTextUTF-8 无 BOM→ **单独**scp上传 →ssh "chmod +x /tmp/x.sh && /tmp/x.sh"执行。注意echo | base64 -d | bash` 会被 PowerShell 工具安全策略直接拦截("Spawning a non-PowerShell shell")。
  • 多源文件 scp 不可靠2026-09-13 实测):一次 scp a b c d e host:/tmp/ 只落地了其中 2 个,且没有任何报错每次只 scp 一个文件;脚本内用 for + [ -f ] 判断做幂等补齐,避免重复上传。
  • 远程脚本一律写成幂等if [ -f ] 判断后再 mv -f),因为 SSH 调用可能被沙箱拦截/用户误拒而中断,重跑不能出错。
  • 别用 echo $LASTEXITCODE 穿透 ssh 取远端退出码2026-09-13 实测踩坑)$LASTEXITCODE 是 PowerShell 自动变量,在本地双引号字符串里就被展开成空串,远端实际收到的是 echo DONE,于是「脚本明明失败了却看到一个成功的回声」。可靠做法:远端 sh /tmp/x.sh > /tmp/x.log 2>&1,再 base64 -w0 /tmp/x.log 回传、本地解码落盘后用 Read 看base64 还能顺带规避 Windows 控制台按 GBK 解 UTF-8 造成的乱码)。
  • set -e + 写死的路径 = 静默失败kuma-statuspage.sh 曾把来源文件写死成 /tmp/wb_kuma_statuspage.sql,而上传的是 /tmp/kuma-statuspage.sql,脚本在第一步就退出,日志只有一行「缺少 …」,看起来像什么都没发生。远程脚本内部一律用 $(dirname "$0")/<同名文件> 推导,再退到 /tmp/<同名文件> 兜底;且上传时保证「脚本名.sh ↔ 同名.sql」成对。
  • SSH 被沙箱拦截时不一定要重试:先找公网可达的旁路做验证。例如 Kuma 的 /api/status-page/<slug>status.xpcool.com 上匿名可达,直接 HTTPS 查就能判断状态页是否建成,省一次权限弹窗。真的需要读远端日志时,再向用户说明并请求重新授权(授权后原命令即可重跑)。
  • 无头 Chrome 截图/量视口有三个坑2026-09-13 实测,做前端移动端验收必看) ① Windows 下窗口宽度有 500px 下限--window-size=390 会被撑到 500--force-device-scale-factor 只改渲染倍率、不改 CSS 视口宽度(给 dsf=2 + window 780拿到的仍是 764 CSS px不是 390 ③ 用iframe 凑窄视口也不可靠——滚动条槽位会让内层 clientWidth 少 15px390 → 375恰好把 390px 下真实存在的横向溢出「藏」起来,导致误判「无溢出」。 正解:走 CDP Emulation.setDeviceMetricsOverride{width:390,height:844,deviceScaleFactor:2,mobile:true}。Node 22 自带全局 WebSocket零依赖即可手写极简 CDP 客户端。整页截图用 Page.captureScreenshot{captureBeyondViewport:true},布局高度仍保持视口高度、不会把 100dvh 的 hero 拉长。参考实现:home.xpcool.com/scripts/shoot-mobile.mjs。 另:无头 Chrome 复用 profile 会导致截到旧产物,每次截图前删掉 $env:TEMP\wb_chrome_*--dump-dom 里搜标记串会撞到脚本源码自身(把结果写进 <title> 再正则取 <title> 才稳)。

本机开发环境:本地 MySQL2026-09-13 搭建)

  • 目的:本地自建库做开发与数据同步;与生产 xpcool-mysql 同版本 8.0.46 + 同字符集 utf8mb4_unicode_cimysqldump 双向无需转换。
  • 落点 E:\Programs\MySQL\(程序 mysql-8.0.46-winx64\、数据 data\、配置 my.ini、日志 logs\、脚本 scripts\)。完整使用说明见 E:\Programs\MySQL\README.md含凭据,不入库)。
  • 端口分工:本地库 3306,生产隧道入口 13306ssh -L 13306:127.0.0.1:3306 → 服务器上只监听回环的 xpcool-mysql),二者互不冲突。
  • 服务化必须管理员:非提权下 mysqld --installInstall/Remove of the Service Denied!。入口 scripts\install-service.bat双击自动 UAC 提权)→ 注册服务 MySQL80(自动启动)+ 目录授权 SYSTEM + 启动 + 初始化账号 + 加用户 PATH过程日志 logs\setup-service.log。脚本幂等(自动识别 root 空密码 / 已设密码两种状态)。
  • 凭据集中在 scripts\credentials.ps1(改密码只改这一处):本地 root/root123456,本地与生产 service 账号同密码(便于同步脚本两边共用一套参数)。生产 root 与 service 见容器 env。密码不入库。
  • 数据同步scripts\pull-prod.ps1 -Database service [-Tables a,b] [-Mode both|schema|data] [-KeepDump] —— 自动确保隧道 → mysqldump 导出 → 导入本地 → 清理临时文件。生产侧用 --single-transaction 快照读,不锁表、不影响写入。注意是覆盖语义(导入前会 DROP 本地同名表)。已冒烟验证:生产 service17 张表完整落到本地。
  • 坑位:用生产 service 账号跑 mysqldump 会报 Access denied ... need PROCESS privilege ... when trying to dump tablespaces--no-tablespaces 消除(已内置于 pull-prod.ps1
  • ⚠️ 沙箱限制(重要,影响所有"常驻进程"类操作)WorkBuddy 的 PowerShell 工具无法创建常驻/提权进程 —— Start-Processshell/解释器目标被「bypass PowerShell command validation」策略拦截、Win32_Process.Create 按等价于 Start-Process 拦截、schtasks.exe 在程序黑名单(提示不可绕过)、cmd.exe 被禁、内置 Bash 缺 dirname/grep/sleep/head 等基础命令。即使 dangerouslyDisableSandbox 也绕不过。结论:注册服务、开隧道、启常驻实例这类操作必须由用户手动执行一次 batAI 负责准备脚本 + 事后验证。

站点与容器清单2026-09-13 核对)

服务器 193.112.118.168,容器均为 restart unless-stopped;除特别标注外只监听 127.0.0.1,由宿主机 nginx 反代。

域名 容器 监听 说明
admin.xpcool.com —(静态 /data/www/ 管理后台前端
service.xpcool.com service.xpcool.com:new 127.0.0.1:10100 Go 后端xpcool-net连 xpcool-mysql
tool.xpcool.com —(静态) 前端工具站
file.xpcool.com fbq 127.0.0.1:10881 FileBrowser Quantum 只读下载
read.xpcool.com qread 127.0.0.1:8082 阅读 legado 自托管
git.xpcool.com gitea + gitea-runner 0.0.0.0:3000 / 0.0.0.0:2222 代码托管与 CI
sub2api.xpcool.com sub2api + postgres + redis 127.0.0.1:18080
code.xpcool.com code-server 127.0.0.1:8080 网页版 VS Code
status.xpcool.com uptime-kuma 127.0.0.1:3001 服务监控面板2026-09-13 新增)
home.xpcool.com —(静态) xpcool 服务台9 站统一入口 + 存活状态。2026-09-13 站点/证书/nginx 已全部上线,/api/kuma/ 同源反代到 Kuma⚠️ 仅剩 DNSPod home A 记录未加,公网暂不可访问
xpcool.com / www.xpcool.com —(静态) 主域名:纯 GPU 实时生成的可交互宇宙Three.js零贴图零模型gzip 后约 171KB。2026-09-13 站点 /data/www/xpcool.com + 证书 + nginx 全部上线,公网 HTTPS 200 / ssl_verify=0 / HTTP 301部署包 E:\CentOS\deploy-xpcool\⚠️ nginx.conf 里已写好 gzip 配置但尚未重新部署,当前 JS/CSS 仍未压缩
—(暂无域名) bark 0.0.0.0:8081 Bark 推送服务端
xpcool-mysql 127.0.0.1:3306 MySQL 8.0(库 service

Uptime Kumastatus.xpcool.com2026-09-13 部署)

  • 镜像 louislam/uptime-kuma:2.5.32.x 稳定线1.x 已停维护v2 有破坏性变更,跨大版本需迁移数据库)。
  • 启动参数:--restart unless-stopped -p 127.0.0.1:3001:3001 -e TZ=Asia/Shanghai -v /data/uptime-kuma:/app/data -v /data/uptime-kuma-patch/bark.js:/app/server/notification-providers/bark.js:ro --memory 512m最后一个 -v 是 Bark 增强补丁挂载2026-09-13 加;没部署前可省略)。服务器内存仅 3.7G 且 swap=0,必须限内存,避免 OOM 波及同机其他容器。
  • v2 首次启动是「选择数据库」引导页(逻辑在 /app/server/setup-database.js,读 data/db-config.json),选 SQLite 即可之后进入创建管理员账号页。Uptime Kuma 没有找回密码入口,密码丢失只能改数据库/清 2FA务必记牢。
  • nginx 反代必须透传 WebSocketproxy_http_version 1.1 + Upgrade/Connection 头),否则面板无限重连、状态刷不出来。
  • 证书:腾讯云免费 DVCN/SAN 均为 status.xpcool.com有效期仅 3 个月(至 2026-12-12到期必须重新申请并替换;落点 /data/nginx/ssl/status.xpcool.com/crt/pem/csr 644、key 600本地源 E:\CentOS\ssl\status.xpcool.com_nginx\。部署时用 openssl x509 -pubkey | md5openssl pkey -pubout | md5 比对,确认证书与私钥配套。
  • 访问形态:http:// → 301 → https://;公网实测 ssl_verify=0、响应约 0.45s2026-09-13
  • nginx 配置模板见 .workbuddy/tmp/status.xpcool.com.conf
  • 监控的添加方式2026-09-13 实测)Uptime Kuma 官方 REST API 不支持创建监控(只能读/暂停/恢复),只能走 Socket.IO需面板账号密码社区库 uptime-kuma-api)或直接写 SQLite。本项目采用后者:向 monitor 表 INSERT字段均有默认值只需给 name/type/url/interval/retry_interval/maxretries/weight/description/accepted_statuscodes_jsonuser_id=1xpcool),再 docker restart uptime-kuma 让服务端重新加载并开始探测。脚本:.workbuddy/tmp/add-monitors.sh(幂等,按 name 去重);改库前先备份 /tmp/kuma.db.backup.<时间戳>
  • heartbeat.status 含义0=DOWN1=UP2=PENDING3=MAINTENANCEmonitor_tls_info 表会自动填充各站点证书信息(可用于证书到期监控)。
  • 第一批监控9 个,均 HTTP(s)、accepted_statuscodes_json=["200-399"]、开启证书到期通知)
    站点 间隔 重试 权重
    admin / service / git 60s 3 1000
    file / read / tool / sub2api 120s 2 2000
    code / status 300s 2 3000
  • service.xpcool.com 单独放宽为 ["200-399","404"]:该后端是纯 POST 接口(遵循本项目"接口全 POST"规范),任何 GET 都 404返回 404 说明 nginx + GoFrame 存活,后端进程真挂时 nginx 返回 502仍会判 DOWN
  • 公开状态页2026-09-13 建,首页状态格的唯一数据源)status.xpcool.com 本身只是 Kuma 面板,状态页是另一回事,必须单独建,否则 /api/status-page/<slug> 恒 404。
    • 三张表配合:status_pageslug/title/published/theme…grouppublic=1status_page_id 指向该页)→ monitor_group(监控与分组的关联)。
    • 必须置 monitor_group.send_url = 1。Kuma 的 Monitor.toPublicJSON()if (this.sendUrl) obj.url = this.customUrl ?? this.url; —— 不开 send_url 时 API 不返回 url 字段。而前端就是靠 url 里的主机名把监控和卡片对齐的,不返回就等于状态全「未接入」。
    • 当前实例slug xpcool(与 home.xpcool.com/src/composables/useStatus.tsSTATUS_PAGE_SLUG 一致、title「xpcool 服务台」、theme dark、search_engine_index=0(内部站不收录)、show_certificate_expiry=1auto_refresh_interval=60分组「自建服务」9 个监控全挂且 send_url=1
    • 建页脚本(幂等,含 DB 备份):E:\CentOS\deploy-home\kuma-statuspage.{sql,sh}改库后必须 docker restart uptime-kuma 才生效。
    • 验证端点:/api/status-page/<slug>(分组+监控列表)与 /api/status-page/heartbeat/<slug>heartbeatList/uptimeList,键形如 "3_24",前缀是监控 id这两个端点在 status.xpcool.com 上公网匿名可达SSH 被拦时可直接用 HTTPS 验证状态页是否建成。
    • 回滚:sudo cp /tmp/kuma.db.backup.<时间戳> /data/uptime-kuma/kuma.db && sudo docker restart uptime-kuma
  • 通知渠道 = Bark2026-09-13 已配置并验证)Kuma 2.5.3 原生支持 Bark/app/server/notification-providers/bark.js)。notification 表:id/name/active/user_id/is_default/configconfig 是整条通知对象的 JSON 字符串(含 typeKuma 用 providerList[notification.type] 派发,靠 item.name 索引
    • 最大的坑:type 必须写 Bark(首字母大写),不是 bark。前端 NotificationDialog.vue:257 就是 Bark: "Bark";写成小写则查不到 provider静默不发通知
    • 当前配置:id=1 / name='Bark 手机推送' / is_default=1config = {"type":"Bark","barkEndpoint":"http://172.17.0.1:8081/sm5WnyANWx89GgLtFnRXhk","barkGroup":"Uptime-Kuma","apiVersion":"v1"}
    • 端点必须用容器网关 172.17.0.1:8081kuma 在默认 bridge 网络(网关 172.17.0.1),容器内的 127.0.0.1 不是宿主机Bark 容器端口发布在宿主机 0.0.0.0:8081,故走网关可达(实测 200
    • apiVersion:"v1" → 走 GET {endpoint}/{title}/{body}?icon=…&group=…&sound=…bark-server 支持);不填也默认 v1。Bark key 就是 /etc/server-monitor.confBARK_URL 那个(sm5WnyANWx89GgLtFnRXhk),手机端就是 https://service.xpcool.com/bark/<key>/
    • 挂到监控:monitor_notification(monitor_id, notification_id)等价于 UI 的 applyExisting。已为 9 个监控全部关联(共 9 行)。
    • 脚本:.workbuddy/tmp/kuma-bark-setup.sh(幂等写入)、.workbuddy/tmp/kuma-bark-verify.sh(端到端验证 + 自清理);改库前必备份 /tmp/kuma.db.backup.<时间戳>
    • 端到端验证方法(推荐复用):临时插一个指向 http://127.0.0.1:9/ 的监控(interval=20/retry_interval=20/maxretries=0)→ 重启容器 → 十几秒即 DOWN 并推送 → 查 docker logs bark 确认真的收到 GET 推送200→ 删掉临时监控与其 heartbeat 再重启。全程不清真站点,可靠性最高。
    • 全部 9 个监控 expiry_notification=1(证书到期通知已开),当前均 UP。
  • Bark 通知增强2026-09-13 · 自定义图标/分组/重要警告/图片/角标) 补丁与素材已备好,待执行部署(沙箱连续拦截 SSH改由 .workbuddy/tmp/deploy-bark-custom.ps1 由用户本机一键执行)。官方 provider 只支持 barkEndpoint/barkGroup/barkSound,且图标写死 GitHub 上的 Kuma logo。扩展办法 = 用只读挂载覆盖 provider 单文件
    • 宿主机 /data/uptime-kuma-patch/bark.js ←→ 容器 /app/server/notification-providers/bark.js:ro)。补丁源码在 .workbuddy/tmp/bark.js,改动点集中在 statusParams()additionalParameters()均以中文注释标了「xpcool 定制」。
    • 行为DOWN → level=critical(重要警告,穿透静音/专注)+ volume=5 + badge=auto(角标自增)+ isArchive=1 + 异常配图UP → badge=0(清角标)+ 恢复配图。call=1(持续响铃 30s默认关闭,要开就在 config 里加 "barkCall": true
    • 所有项都可用通知 config 里的同名字段覆盖:barkIcon / barkGroup / barkSound / barkLevel / barkVolume / barkCall / barkBadge / barkImageDown / barkImageUp / barkBadgeReset但 UI 里保存通知会重写 config、丢掉这些额外字段 —— 保持默认行为即可(补丁有兜底默认值),要改就走 SQL。
    • 素材自托管在 https://status.xpcool.com/bark-assets/{icon,down,up}.png(落点 /data/www/bark-assets/nginx 新增 location /bark-assets/alias + default_type image/png + expires 7d)。必须公网 HTTPS 可匿名访问:图是手机端收到通知后自己去拉的。
    • 素材由 .workbuddy/tmp/make-bark-assets.pyPillow 手绘)生成,纯几何 + 微软雅黑文字,体积 22~78 KB。
    • ⚠️ 升级 uptime-kuma 镜像后bark.js 会被挂载覆盖成旧版实现,必须重新对照新版官方 bark.js 更新补丁(或临时去掉挂载)。
    • ⚠️ 重建容器必须带回挂载,否则补丁失效(表现为:通知还发,但图标/重要警告/配图/角标全没了)。完整启动参数见上。
    • 部署脚本:.workbuddy/tmp/deploy-bark-custom.sh(远端执行,幂等)+ .workbuddy/tmp/deploy-bark-custom.ps1(本机一键:上传 → 部署 → 端到端验证,日志写 .workbuddy/tmp/logs/)。