{"id":34647040,"url":"https://github.com/xhhcn/pulse","last_synced_at":"2026-05-05T01:01:38.471Z","repository":{"id":329276464,"uuid":"1118811535","full_name":"xhhcn/Pulse","owner":"xhhcn","description":"Lightweight server monitoring","archived":false,"fork":false,"pushed_at":"2026-05-04T23:05:33.000Z","size":111104,"stargazers_count":114,"open_issues_count":4,"forks_count":16,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T00:27:31.176Z","etag":null,"topics":["golang","monitor","services"],"latest_commit_sha":null,"homepage":"https://xhh.ovh","language":"Astro","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xhhcn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-18T10:07:53.000Z","updated_at":"2026-05-04T23:05:35.000Z","dependencies_parsed_at":"2025-12-26T22:04:29.165Z","dependency_job_id":null,"html_url":"https://github.com/xhhcn/Pulse","commit_stats":null,"previous_names":["xhhcn/pulse"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/xhhcn/Pulse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xhhcn%2FPulse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xhhcn%2FPulse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xhhcn%2FPulse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xhhcn%2FPulse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xhhcn","download_url":"https://codeload.github.com/xhhcn/Pulse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xhhcn%2FPulse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32631058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"ssl_error","status_checked_at":"2026-05-04T10:08:02.005Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","monitor","services"],"created_at":"2025-12-24T17:47:58.533Z","updated_at":"2026-05-05T01:01:38.464Z","avatar_url":"https://github.com/xhhcn.png","language":"Astro","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.svg\" width=\"120\" height=\"120\" alt=\"Pulse Logo\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003ePulse\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003e轻量级服务器监控系统\u003c/b\u003e\u003cbr\u003e\n  实时监控 CPU、内存、磁盘、网络等指标\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"README_EN.md\"\u003eEnglish\u003c/a\u003e | \u003ca href=\"README.md\"\u003e中文\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/xhhcn/Pulse/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/xhhcn/Pulse?style=flat-square\u0026color=blue\" alt=\"Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://hub.docker.com/r/xhh1128/pulse\"\u003e\u003cimg src=\"https://img.shields.io/docker/pulls/xhh1128/pulse?style=flat-square\u0026color=blue\" alt=\"Docker Pulls\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://hub.docker.com/r/xhh1128/pulse\"\u003e\u003cimg src=\"https://img.shields.io/docker/image-size/xhh1128/pulse/latest?style=flat-square\u0026color=blue\" alt=\"Docker Size\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/xhhcn/Pulse?style=flat-square\u0026color=green\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Go-1.21+-00ADD8?style=flat-square\u0026logo=go\u0026logoColor=white\" alt=\"Go\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Astro-4.0+-FF5D01?style=flat-square\u0026logo=astro\u0026logoColor=white\" alt=\"Astro\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Platform-amd64%20%7C%20arm64-lightgrey?style=flat-square\" alt=\"Platform\"\u003e\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  由 \u003ca href=\"https://www.dooki.cloud\" target=\"_blank\"\u003e\u003cb\u003eDokiDoki CDN\u003c/b\u003e\u003c/a\u003e 赞助\u003cbr\u003e\u003cbr\u003e\n  \u003ca href=\"https://www.dooki.cloud\" target=\"_blank\"\u003e\n    \u003cimg src=\"assets/doki.png\" height=\"60\" alt=\"DokiDoki CDN\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## ✨ v1.3.0 新功能\n\n- 🔐 **共享密钥认证** - 所有客户端使用统一的共享密钥连接服务器，简化部署配置\n- 🏷️ **特殊标签支持** - 新增 `traffic:in/out` 和 `speed:in/out` 标签，实时显示流量统计和网络速率\n- 🎨 **自定义 CSS/JS** - 支持全站自定义样式和脚本，打造个性化监控面板\n\n---\n\n## 🚀 服务端安装\n\n### 方式一：独立二进制部署（推荐新手和 VPS 用户）\n\n#### 一键安装\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/xhhcn/Pulse/main/install-pulse-server.sh | sudo bash\n```\n\n脚本会自动：\n- ✅ 检测系统架构（amd64 / arm64）\n- ✅ 下载对应的二进制到 `/opt/pulse/pulse-server`\n- ✅ 配置 `pulse-server.service` 并设置开机自启\n- ✅ 顺手装上迁移辅助脚本 `/opt/pulse/scripts/{backup,restore,migrate}.sh`，并创建 `pulse-backup` / `pulse-restore` / `pulse-migrate` 三个 CLI 短链（详见 [迁移到另一台服务器](#-迁移到另一台服务器)）\n\n#### 更新服务端\n\n**amd64:**\n```bash\nsudo systemctl stop pulse-server \u0026\u0026 sudo wget https://github.com/xhhcn/Pulse/releases/latest/download/pulse-server-standalone-linux-amd64 -O /opt/pulse/pulse-server \u0026\u0026 sudo chmod +x /opt/pulse/pulse-server \u0026\u0026 sudo systemctl start pulse-server\n```\n\n**arm64:**\n```bash\nsudo systemctl stop pulse-server \u0026\u0026 sudo wget https://github.com/xhhcn/Pulse/releases/latest/download/pulse-server-standalone-linux-arm64 -O /opt/pulse/pulse-server \u0026\u0026 sudo chmod +x /opt/pulse/pulse-server \u0026\u0026 sudo systemctl start pulse-server\n```\n\n#### 卸载服务端\n\n\u003e 一键安装脚本除了主程序还会落地三件东西：迁移辅助脚本 `/opt/pulse/scripts/{backup,restore,migrate}.sh`、`/usr/local/bin/pulse-{backup,restore,migrate}` 三个 CLI 短链，以及 `/opt/pulse/data/`（数据库 `metrics.db` 在这里）。卸载时按需选择以下两种之一：\n\n**仅删除程序（保留 `/opt/pulse/data/` 下的数据库，方便回滚或日后重装）:**\n```bash\nsudo systemctl stop pulse-server \u0026\u0026 sudo systemctl disable pulse-server \u0026\u0026 \\\nsudo rm -f /usr/local/bin/pulse-migrate /usr/local/bin/pulse-backup /usr/local/bin/pulse-restore \u0026\u0026 \\\nsudo rm -f /opt/pulse/pulse-server /etc/systemd/system/pulse-server.service \u0026\u0026 \\\nsudo rm -rf /opt/pulse/scripts \u0026\u0026 \\\nsudo systemctl daemon-reload\n```\n\n**完全删除（包括数据库 `metrics.db`，不可逆）:**\n```bash\nsudo systemctl stop pulse-server \u0026\u0026 sudo systemctl disable pulse-server \u0026\u0026 \\\nsudo rm -f /usr/local/bin/pulse-migrate /usr/local/bin/pulse-backup /usr/local/bin/pulse-restore \u0026\u0026 \\\nsudo rm -f /etc/systemd/system/pulse-server.service \u0026\u0026 \\\nsudo rm -rf /opt/pulse \u0026\u0026 \\\nsudo systemctl daemon-reload\n```\n\n#### 手动安装\n\n**Linux (amd64)**\n```bash\n# 下载\nwget https://github.com/xhhcn/Pulse/releases/latest/download/pulse-server-standalone-linux-amd64\nchmod +x pulse-server-standalone-linux-amd64\n\n# 运行\n./pulse-server-standalone-linux-amd64\n```\n\n**Linux (arm64)**\n```bash\n# 下载\nwget https://github.com/xhhcn/Pulse/releases/latest/download/pulse-server-standalone-linux-arm64\nchmod +x pulse-server-standalone-linux-arm64\n\n# 运行\n./pulse-server-standalone-linux-arm64\n```\n\n访问 `http://YOUR_IP:8008` 查看监控面板\n\n---\n\n### 方式二：Docker 部署（推荐生产环境）\n\n[![Docker](https://img.shields.io/badge/Docker-xhh1128/pulse-2496ED?style=for-the-badge\u0026logo=docker\u0026logoColor=white)](https://hub.docker.com/r/xhh1128/pulse)\n\n#### Docker Compose\n\n```bash\nmkdir pulse \u0026\u0026 cd pulse\ncurl -sSL https://raw.githubusercontent.com/xhhcn/Pulse/main/docker-compose.yaml -o docker-compose.yaml\ndocker compose up -d\n```\n\n\u003e **IPv6 支持**：如果您的服务器需要 IPv6 支持，请参考下方的 [Docker IPv6 配置](#docker-ipv6-配置) 章节。\n\n#### Docker Run\n\n```bash\ndocker run -d \\\n  --name pulse-monitor \\\n  -p 8008:8008 \\\n  -v $(pwd)/pulse-data:/app/data \\\n  --restart unless-stopped \\\n  xhh1128/pulse:latest\n```\n\n访问 `http://YOUR_IP:8008` 查看监控面板\n\n---\n\n## 🌐 Docker IPv6 配置\n\nPulse 支持 IPv4/IPv6 双栈，如果您的服务器需要 IPv6 支持，请按照以下步骤配置：\n\n### 前置要求\n\n1. **确保宿主机已启用 IPv6**\n   ```bash\n   # 检查 IPv6 是否启用\n   ip -6 addr show\n   \n   # 检查 IPv6 转发是否启用\n   sysctl net.ipv6.conf.all.forwarding\n   # 如果输出为 0，需要启用：\n   sudo sysctl -w net.ipv6.conf.all.forwarding=1\n   \n   # 永久启用（编辑 /etc/sysctl.conf）\n   echo \"net.ipv6.conf.all.forwarding=1\" | sudo tee -a /etc/sysctl.conf\n   ```\n\n2. **配置 Docker Daemon 启用 IPv6**\n\n   编辑或创建 `/etc/docker/daemon.json`：\n   ```json\n   {\n     \"ipv6\": true,\n     \"fixed-cidr-v6\": \"fd00:dead:beef:c0::/80\",\n     \"experimental\": true,\n     \"ip6tables\": true\n   }\n   ```\n   \n   \u003e **说明**：\n   \u003e - `ipv6: true` - 全局启用 Docker 的 IPv6 支持（**必需**）\n   \u003e - `fixed-cidr-v6` - Docker 使用的 IPv6 子网范围（可根据实际情况调整）\n   \u003e - `experimental: true` - 启用实验性功能（某些 IPv6 功能需要）\n   \u003e - `ip6tables: true` - 启用 IPv6 的 iptables 支持（用于网络隔离和端口映射）\n   \n   重启 Docker 服务使配置生效：\n   ```bash\n   sudo systemctl restart docker\n   ```\n\n3. **配置 docker-compose.yaml 启用 IPv6**\n\n   在 `docker-compose.yaml` 中配置网络启用 IPv6：\n   ```yaml\n   services:\n     pulse:\n       image: xhh1128/pulse:latest\n       container_name: pulse-monitor\n       ports:\n         - 8008:8008\n       volumes:\n         - pulse-data:/app/data\n       restart: unless-stopped\n       networks:\n         - pulse-network\n\n   volumes:\n     pulse-data:\n\n   networks:\n     pulse-network:\n       enable_ipv6: true\n       ipam:\n         driver: default\n   ```\n\n4. **重新创建容器**\n\n   ```bash\n   docker compose down\n   docker compose up -d\n   ```\n\n5. **验证 IPv6 配置**\n\n   ```bash\n   # 检查容器 IPv6 地址\n   docker exec pulse-monitor ip -6 addr show\n   \n   # 测试 IPv6 连接（如果容器有 ping6）\n   docker exec pulse-monitor ping6 -c 2 2001:4860:4860::8888\n   ```\n\n---\n\n## 📦 客户端安装\n\n### Linux\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/xhhcn/Pulse/main/client/install.sh | sudo bash -s -- \\\n  --id \u003cID\u003e --server \u003cSERVER_URL\u003e --secret \u003cSECRET\u003e\n```\n\n### macOS（Intel / Apple Silicon）\n\n安装脚本会自动检测 CPU 架构，并将服务注册为 `launchd` 守护进程（开机自动启动）：\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/xhhcn/Pulse/main/client/install.sh | sudo bash -s -- \\\n  --id \u003cID\u003e --server \u003cSERVER_URL\u003e --secret \u003cSECRET\u003e\n```\n\n\u003e **注意**：macOS 需要 `sudo` 权限以便将 `.plist` 写入 `/Library/LaunchDaemons/`。\n\n**macOS 服务管理命令：**\n\n```bash\n# 查看运行状态\nsudo launchctl print system/com.pulse.client\n\n# 查看日志\ntail -f /var/log/pulse-client.log\n\n# 重启服务（推荐方式）\nsudo launchctl kickstart -k system/com.pulse.client\n\n# 停止服务\nsudo launchctl bootout system/com.pulse.client\n\n# 重新启动已停止的服务\nsudo launchctl bootstrap system /Library/LaunchDaemons/com.pulse.client.plist\n```\n\n### Windows (管理员 PowerShell)\n\n```powershell\npowershell -ExecutionPolicy Bypass -Command \"\u0026 { $env:AgentId='\u003cID\u003e'; $env:ServerBase='\u003cSERVER_URL\u003e'; $env:Secret='\u003cSECRET\u003e'; irm https://raw.githubusercontent.com/xhhcn/Pulse/main/client/install.ps1 | iex }\"\n```\n\n| 参数 | 说明 |\n|------|------|\n| `\u003cID\u003e` | 服务器唯一标识（在管理后台添加系统时设置） |\n| `\u003cSERVER_URL\u003e` | 服务端地址，如 `http://your-server:8008` |\n| `\u003cSECRET\u003e` | 认证密钥（在管理后台添加系统后自动生成，可在系统详情中查看） |\n\n\u003e **注意**：`--secret` 参数是可选的。如果服务端系统配置了 secret，则必须提供正确的 secret 才能成功注册。\n\n### 卸载客户端\n\n\u003e 客户端默认开启自动更新，因此 systemd 上除了 `pulse-client.service` 还有 `pulse-client-update.service` + `pulse-client-update.timer` 两件，macOS 上则多一个 `com.pulse.client.update` 守护进程。下面的命令同时清理这些组件，无论之前是否启用过自动更新都能安全运行（缺失的 unit 会被忽略）。\n\n**Linux (systemd):**\n```bash\nsudo systemctl stop pulse-client pulse-client-update.timer 2\u003e/dev/null\nsudo systemctl disable pulse-client pulse-client-update.timer 2\u003e/dev/null\nsudo rm -f /opt/pulse/probe-client /opt/pulse/update.sh \\\n  /etc/systemd/system/pulse-client.service \\\n  /etc/systemd/system/pulse-client-update.service \\\n  /etc/systemd/system/pulse-client-update.timer\nsudo systemctl daemon-reload\n```\n\u003e 同一台机器若同时跑了服务端，请保留 `/opt/pulse/`（仅删上面列出的客户端相关文件即可），数据库不受影响。\n\n**macOS（含自动更新）:**\n```bash\nsudo launchctl bootout system/com.pulse.client 2\u003e/dev/null || true\nsudo launchctl bootout system/com.pulse.client.update 2\u003e/dev/null || true\nsudo rm -rf /opt/pulse \\\n  /Library/LaunchDaemons/com.pulse.client.plist \\\n  /Library/LaunchDaemons/com.pulse.client.update.plist\n```\n\n**Windows (管理员 PowerShell):**\n```powershell\nStop-ScheduledTask -TaskName 'PulseClient' -ErrorAction SilentlyContinue; Unregister-ScheduledTask -TaskName 'PulseClient' -Confirm:$false -ErrorAction SilentlyContinue; Remove-NetFirewallRule -DisplayName 'Pulse Monitoring Client*' -ErrorAction SilentlyContinue; Remove-Item -Path \"$env:ProgramFiles\\Pulse\" -Recurse -Force -ErrorAction SilentlyContinue\n```\n\n---\n\n## ⚙️ 使用方法\n\n1. 访问 `http://YOUR_IP:8008/admin` 进入管理后台\n2. 首次访问设置管理密码\n3. 点击 **Add System** 添加服务器\n4. 添加系统后，系统会自动生成一个 **Secret**（认证密钥）\n5. 在目标机器上运行客户端安装命令，**必须包含正确的 Secret**\n6. 数据自动上报，实时显示\n\n\u003e **提示**：在管理后台的系统列表中，点击系统右侧的复制按钮可以快速复制包含 Secret 的安装命令。\n\n---\n\n## 📊 监控指标\n\n| 指标 | 内容 |\n|------|------|\n| **CPU** | 使用率、核心数、型号 |\n| **内存** | 使用率、总量 |\n| **磁盘** | 使用率、总量 |\n| **网络** | 上传/下载速率、TCPing延迟 |\n| **系统** | 运行时间、IP、位置 |\n\n---\n\n## 🚚 迁移到另一台服务器\n\nPulse 服务端的全部状态（系统列表、共享密钥、TCPing 历史、管理员密码、面板配置……）都只保存在 **一个 bbolt 文件** 里。仓库提供的 `scripts/migrate.sh` 把整个流程打包成 **一条命令**：在新服务器上跑一次，就能从旧服务器把所有数据搬过来，**旧服务器全程不停机、零数据丢失**。\n\n\u003e 客户端 `AGENT_ID` / `SECRET` 保持不变，只有 `SERVER_BASE`（服务端地址）可能需要改。  \n\u003e 如果旧端用的是域名 + 反代，只需把 DNS 切到新 IP 即可，客户端完全不用动。\n\n### ✨ 一条命令完成迁移\n\n```bash\n# ── 在新服务器上 ──\n\n# 1) 安装 Pulse（二选一）\n#    A. 独立二进制（systemd） — 推荐，资源占用最小\n#       安装器会顺便把 backup/restore/migrate 脚本装到 /opt/pulse/scripts/\n#       并创建 pulse-migrate / pulse-backup / pulse-restore 三个命令。\ncurl -fsSL https://raw.githubusercontent.com/xhhcn/Pulse/main/install-pulse-server.sh | sudo bash\n\n#    B. Docker Compose\n# mkdir pulse \u0026\u0026 cd pulse \u0026\u0026 \\\n# curl -sSL https://raw.githubusercontent.com/xhhcn/Pulse/main/docker-compose.yaml -o docker-compose.yaml \u0026\u0026 \\\n# docker compose up -d \u0026\u0026 \\\n# curl -fsSL https://raw.githubusercontent.com/xhhcn/Pulse/main/scripts/migrate.sh -o migrate.sh \u0026\u0026 chmod +x migrate.sh\n#       migrate.sh 会自动从仓库拉取它所依赖的 backup.sh / restore.sh，一个文件够用\n\n# 2) 一条命令迁移 —— 交互式输入旧服务器的管理员密码\nsudo pulse-migrate --from https://OLD_HOST                 # 二进制方式（最便捷）\n# 或在 Docker 目录里：\n# sudo ./migrate.sh --from https://OLD_HOST\n\n# 非交互（CI/自动化，推荐用 env var 避免密码进 `ps`）：\n# sudo PASSWORD='旧服务器密码' pulse-migrate --from https://OLD_HOST -y\n```\n\n`migrate.sh` 按顺序完成：\n\n1. 用你提供的密码登录 **旧服务器**，换取一次性管理员令牌（密码通过 stdin 传给 `curl`，不会出现在 `ps` 里）。\n2. 调用 `GET /api/admin/backup` 拉一份 **事务级一致性** 的热备份——基于 bbolt 的 `Tx.WriteTo`，不会捕获到半写入页，**旧服务器不停机**。\n3. 校验下载文件：大小 + bbolt 魔数 `0xEDDA0CED`，避免 `scp` 断流或误传成 `.gz` 直接使用。\n4. 自动识别新服务器是 **Docker** 还是 **独立二进制**，停服 → 把当前 `metrics.db` 另存为 `metrics.db.pre-restore-\u003c时间戳\u003e`（一条命令回滚）→ 放入新文件 → 重启服务。\n5. 轮询 `/healthz` 直到返回 200，或 60 秒超时后打印日志并给出回滚命令。\n\n默认把下载的备份文件放在权限 `0700` 的私有临时目录，文件本身 `0600`，成功后自动清理；加 `--keep-backup ./pulse-backup.db` 可以保留一份做离线归档。\n\n### 💾 只想手动备份？管理面板一键下载\n\n进 `/admin` 登录后，表头右上角多了一个 **下载备份** 按钮（下载图标，绿色悬停色）。点一下浏览器就会保存一个 `pulse-backup-\u003cUTC 时间戳\u003e.db` —— 跟 `pulse-backup` / `migrate.sh` 拉到的**完全是同一个文件**（事务级一致热快照，基于 `Tx.WriteTo`），可以直接喂给 `sudo pulse-restore \u003c文件\u003e` 在任意新机器上还原。适合：没 SSH 环境、想快速做一次性备份、或者给迁移留个保险。\n\n### 🔐 安全要点（认真看一眼，30 秒）\n\n- **用 HTTPS 或 SSH 隧道**。备份里带着管理员密码哈希 + 每台机器的共享密钥，纯 HTTP 走公网等于把钥匙挂外面。脚本会在检测到非本地 `http://` 时弹出提醒。没有 HTTPS 时推荐：\n  ```bash\n  ssh -fN -L 8008:localhost:8008 user@OLD_HOST\n  sudo pulse-migrate --from http://localhost:8008\n  ```\n- **别用 `--password '明文'`**。命令行参数在 `ps` 里所有本机用户都看得到。优先：交互式提示（无参数）或环境变量 `PASSWORD='...' pulse-migrate ...`。\n- **备份文件 = 生产 DB**。保存时用 `0600` 权限（脚本已做），传输时走加密通道，不用了就删。\n- **服务端已经做了多层防护**：登录 5 次失败锁 IP 15 分钟、密码 bcrypt、`/api/admin/backup` 只认 `Authorization: Bearer`（拒绝 `?token=` query，避免令牌进 nginx 日志）、每次备份都会写一条审计日志（包含客户端 IP）。\n\n### 🔁 客户端地址更新（仅当 URL 变了）\n\n```bash\n# Linux（systemd 客户端）\nsudo sed -i 's#http://OLD_HOST:8008#http://NEW_HOST:8008#g' \\\n  /etc/systemd/system/pulse-client.service\nsudo systemctl daemon-reload \u0026\u0026 sudo systemctl restart pulse-client\n```\n\n### 🛡️ 回滚\n\n旧的 `metrics.db` 在迁移时被自动备份为 `metrics.db.pre-restore-\u003c时间戳\u003e`，随时可以回滚：\n\n```bash\n# 独立二进制\nsudo systemctl stop pulse-server\nsudo cp /opt/pulse/data/metrics.db.pre-restore-* /opt/pulse/data/metrics.db\nsudo systemctl start pulse-server\n\n# Docker\ndocker compose stop\ncp datatz/metrics.db.pre-restore-* datatz/metrics.db\ndocker compose up -d\n```\n\n在 `/admin` 登录正常、系统列表齐全、TCPing 图表渲染正常后，再删除这些 `.pre-restore-*` 文件即可。\n\n### 📅 顺便：周期性备份\n\n同一套脚本可以挂到 cron 做日常热备（零停机）：\n\n```bash\n# 每天 UTC 03:00 一次，环境变量传密码避免 ps 泄漏\n0 3 * * * PASSWORD='YourAdminPW' /opt/pulse/scripts/backup.sh \\\n  --server http://127.0.0.1:8008 \\\n  --output /var/backups/pulse/pulse-$(date -u +\\%Y\\%m\\%d).db\n```\n\n### ⚠️ 注意事项\n\n- **备份文件等同于全部密钥**：里面包含所有系统的共享密钥和管理员密码哈希，和生产 DB 一样谨慎对待（文件权限、传输通道）。\n- **不要同时运行两台服务端指向同一套客户端**——客户端会上报给最先通的那台，数据会分裂。迁移完成后及时下线旧端。\n- **脚本参数全览**：`pulse-migrate --help`、`pulse-backup --help`、`pulse-restore --help`（或直接 `/opt/pulse/scripts/*.sh --help`）。\n\n---\n\n## ✨ 新特征\n\n- 私有化模式\n- Logo和名称自定义\n- CPU类型检测\n- 客户端一键部署\n\n---\n\n## 📄 License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxhhcn%2Fpulse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxhhcn%2Fpulse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxhhcn%2Fpulse/lists"}