# NGS API Server 基于 ylib `httpserver` 的 NGS 管理 API。默认监听 **`0.0.0.0:15665`**。 内置可视化控制台目录:`data/www`,浏览器打开: ```text http://127.0.0.1:15665/ ``` ## 启动 ```bash ./br.sh # 或 ./build/ngs # 自定义监听 ./build/ngs --listen 0.0.0.0 --port 15665 ``` 面板路径可通过环境变量覆盖:`NGS_PANEL_WWW=/path/to/www`。 数据存储:站点元数据、MySQL 账号/密码/权限、root 密码与监听地址保存在 SQLite:`data/database.db`(可用 `NGS_DATABASE` 覆盖)。Nginx 的 `www/conf/vhost/*.conf` 仍为文件。 统一响应格式: ```json { "code": 200, "msg": "ok", "data": {} } ``` - `code = 200` 表示成功 - 失败时 `code` 为负数或 HTTP 语义码(如 `404`/`405`/`401`),`msg` 为错误信息 --- ## 登录鉴权 管理面板与 `/api/*`(除登录相关)需登录。账号密码配置文件: ```text www/conf/ngs.conf ``` 首次启动若不存在会自动生成,默认: ```text username=admin password=ngsadmin ``` 修改配置后需**重启 ngs** 生效。浏览器使用 Cookie `ngs_session`。 | 方法 | 路径 | 说明 | Body | |------|------|------|------| | POST | `/api/auth/login` | 登录 | `{"username":"admin","password":"..."}` | | POST | `/api/auth/logout` | 退出 | `{}` | | GET | `/api/auth/me` | 当前用户(未登录返回 401) | - | --- ## 系统 ### `GET /api/ping` 健康检查。 ### `GET /api/status` 汇总 Nginx / Fastweb / MySQL / Redis / 网站数量状态(含各组件 `conf` 配置路径)。 ### 任务队列 长任务(安装/卸载)进入后台队列,立即返回 `task_id`。状态持久化到 `www/conf/tasks.json`,日志在 `www/conf/tasks/.log`。 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/tasks` | 任务列表与 `active` 数量 | | GET | `/api/tasks/log?id=&offset=` | 增量拉取任务日志 | | POST | `/api/tasks/clear` | 清理已完成/失败任务 | 安装类接口响应示例: ```json { "code": 200, "msg": "task queued", "data": { "task_id": "t...", "active": 1 } } ``` ### `GET /api/system/metrics` 当前瞬时 CPU / 内存 / 磁盘 / 网络。 ### `GET /api/system/metrics/history` 后台每 2 秒采集并写入 `data/metrics.db`,按时间范围查询(默认 `10m`)。 | 参数 | 说明 | |------|------| | `range` | `1m` / `10m` / `30m` / `1h` / `6h` / `1d` / `7d` / `30d` | ### `GET /api/system/processes` 列出当前系统进程(读 `/proc`)。 | 参数 | 说明 | |------|------| | `q` | 可选,按 PID / 用户 / 名称 / 运行目录 / 命令行过滤 | ```json { "total": 120, "items": [ { "pid": 1, "ppid": 0, "user": "root", "state": "S", "name": "systemd", "cmdline": "/sbin/init", "cwd": "/", "threads": 1, "rss": 10485760, "vms": 167772160, "mem_percent": 0.5, "cpu_percent": 0.1 } ] } ``` ### WebSocket `/api/shell/ws?ticket=` 交互式终端。先 `GET /api/shell/ticket`(需登录 Cookie)拿到一次性票据,再升级 WebSocket。 - 握手:只回 `101 Switching Protocols`(不回 JSON body) - 客户端 → 服务端:原始键入,或 `{"type":"resize","cols":120,"rows":40}` - 服务端 → 客户端:PTY 输出(二进制帧) - 同时最多 8 个会话;断开连接自动回收 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/shell/ticket` | 签发 60s 一次性 WS ticket | | WS | `/api/shell/ws?ticket=` | 终端通道 | ### `POST /api/system/processes/kill` 结束进程(默认 `SIGTERM`)。 ```json { "pid": 12345, "signal": 15, "signal_name": "TERM" } ``` - `signal` / `signal_name`:`TERM`(15) / `KILL`(9) / `INT`(2) / `HUP`(1) - 拒绝 `PID <= 1` ```json { "range": "10m", "items": [ { "time_ms": 1786430100000, "cpu_percent": 12.5, "cpu_cores": 8, "mem_percent": 40.1, "mem_used": 1000, "mem_total": 2000, "disk_percent": 20.0, "disk_used": 100, "disk_total": 500, "net_rx_bps": 1024.5, "net_tx_bps": 512.0 } ] } ``` 数据保留约 30 天;长区间会自动降采样。 --- ## Redis | 方法 | 路径 | 说明 | Body | |------|------|------|------| | GET | `/api/redis/status` | 状态 | - | | POST | `/api/redis/install` | 源码安装 | `{"version":"7.2.5"}`(可选) | | POST | `/api/redis/uninstall` | 卸载 | - | | POST | `/api/redis/start` | 启动 | - | | POST | `/api/redis/stop` | 停止 | - | 默认安装目录:`www/software/redis`。默认端口 `6379`,占用时回退 `6380`。 --- ## 文件管理 全盘路径,根目录从 `/` 起。 | 方法 | 路径 | 说明 | Body / Query | |------|------|------|------| | GET | `/api/files/list` | 列目录 | `?path=/` | | POST | `/api/files/mkdir` | 新建目录 | `{"path":"/tmp/a"}` | | POST | `/api/files/write` | 写文本/新建文件 | `{"path":"/tmp/a.txt","content":"..."}` | | GET | `/api/files/read` | 读文本(最大 **10MB**,超限拒绝) | `?path=/tmp/a.txt` | | GET | `/api/files/tail` | 读文件尾部(默认 256KB) | `?path=/tmp/a.log&bytes=262144` | | POST | `/api/files/rename` | 重命名/移动 | `{"from":"...","to":"..."}` | | POST | `/api/files/delete` | 删除 | `{"path":"...","recursive":false}` | | POST | `/api/files/upload` | 上传 | `{"path":"...","content_base64":"..."}` 或 `content` | | GET | `/api/files/download` | 下载文件 | `?path=/tmp/a.txt`(直接文件流) | 目录删除需 `recursive=true` 才会递归;默认仅删空目录或文件。 在线编辑/预览使用 Monaco(VS Code 同款编辑器),仅支持 **≤10MB** 文本文件;超过 10MB 不可预览、不可编辑(仍可下载)。`POST /api/files/write` 同样拒绝超过 10MB 的内容。 --- ## Nginx | 方法 | 路径 | 说明 | Body | |------|------|------|------| | GET | `/api/nginx/status` | 状态 | - | | POST | `/api/nginx/install` | 安装 | `{"version":"1.26.3"}`(可选) | | POST | `/api/nginx/uninstall` | 卸载 | - | | POST | `/api/nginx/start` | 启动 | - | | POST | `/api/nginx/stop` | 停止 | - | | POST | `/api/nginx/reload` | 重载配置 | - | | GET | `/api/nginx/config` | 读取基础配置 | - | | POST | `/api/nginx/config` | 保存基础配置并重载 | 见下 | 基础配置 Body: ```json { "worker_processes": "auto", "worker_connections": 1024, "keepalive_timeout": "65", "client_max_body_size": "50m", "gzip": false } ``` 保存后会写入 `nginx.conf`、执行配置检测;若 Nginx 正在运行则自动重载生效。 --- ## Fastweb | 方法 | 路径 | 说明 | Body | |------|------|------|------| | GET | `/api/fastweb/status` | 状态 | - | | POST | `/api/fastweb/install` | 安装 | `{"debug":false}`(可选) | | POST | `/api/fastweb/uninstall` | 卸载 | - | --- ## MySQL | 方法 | 路径 | 说明 | Body | |------|------|------|------| | GET | `/api/mysql/status` | 状态 | - | | POST | `/api/mysql/install` | 安装 | `{"version":"8.0.35"}`(可选) | | POST | `/api/mysql/uninstall` | 卸载 | - | | POST | `/api/mysql/start` | 启动 | - | | POST | `/api/mysql/stop` | 停止 | - | | POST | `/api/mysql/root/password` | 修改 root 密码 | `{"password":"..."}` | | GET | `/api/mysql/databases` | 数据库列表 | - | | POST | `/api/mysql/databases` | 创建数据库 | `{"name":"db","user":"u","password":"p"}` | | POST | `/api/mysql/databases/drop` | 删除数据库 | `{"name":"db"}` | | POST | `/api/mysql/databases/access` | 设置访问权限 | 见下 | 权限设置 Body: ```json { "name": "db", "mode": "local|fixed_ip|any", "host": "1.2.3.4" } ``` - `local`:仅本地 - `fixed_ip`:固定 IP(需 `host`) - `any`:允许外网(`%`) 默认 MySQL 端口:`3307`。 --- ## 网站 | 方法 | 路径 | 说明 | Body | |------|------|------|------| | GET | `/api/websites` | 网站列表 | - | | POST | `/api/websites` | 创建网站 | 见下 | | POST | `/api/websites/update` | 更新域名/端口/证书 | `{"name","domain"|"domains","listen_port",ssl_*}` | | POST | `/api/websites/ssl/apply` | 申请 Let's Encrypt(任务队列,多域名一张证;邮箱自动生成) | `{"name","domains":["a.com","www.a.com"]}` | | POST | `/api/websites/start` | 启动 | `{"name":"demo"}` | | POST | `/api/websites/stop` | 停止 | `{"name":"demo"}` | | POST | `/api/websites/restart` | 重启 | `{"name":"demo"}` | | POST | `/api/websites/delete` | 删除网站 | `{"name":"demo","delete_files":false}` | | GET | `/api/websites/analytics` | 站点日志分析(SQLite 聚合) | `?name=demo&range=24h`(`1h\|6h\|24h\|7d\|30d\|all`) | | GET | `/api/websites/logs` | 访问/错误日志(每站点 SQLite) | `?name=demo&kind=access|error&limit=100&before_id=&status=&ip=&level=` | | POST | `/api/websites/logs/purge` | 清理站点日志文件和/或日志库 | `{"name":"demo","files":true,"db":true}` | 访问日志库路径:`data/log/.db`。表 `access_log` / `error_log`;后台从 `www/log//access.log`、`error.log` 增量入库。 `access_log` 主要字段:`time`(`YYYY-MM-DD HH:MM:SS`)、`time_ms`(毫秒时间戳)、`request_time`(耗时秒)、`bytes_recv`(接收)、`bytes_sent`(发送)。 `delete_files=true` 时同时删除 `wwwroot/` 目录;默认 `false` 仅删配置并保留目录。删除站点时会移除对应 `data/log/.db`。 创建网站 Body: ```json { "name": "demo", "type": "static|fastweb", "domain": "demo.local www.demo.local", "domains": ["demo.local", "www.demo.local"], "listen_port": 8080 } ``` - `domain` / `domains` 可省略,默认等于 `name`;支持多个,格式为 `域名` 或 `域名:端口`(默认 80) - `listen_port` 可省略,由域名条目解析;未写端口时默认 80 - 网站类型仅 `static` / `fastweb`;反向代理请用站点设置中的 URL 代理(`/api/websites/proxies`) - `type=fastweb` 时会自动探测空闲端口并生成站点配置与 `/` URL 代理规则 - SSL:`POST /api/websites/ssl/apply` 使用 Let's Encrypt(HTTP-01),域名需解析到本机且 **80 端口可达** 列表示例字段:`name` / `type` / `domain` / `domains` / `listen_port` / `upstream` / `running` / `root` / `log_dir` / `access_log` / `error_log` / `log_db` / `log_file_bytes` / `log_db_bytes` / `log_bytes` / `conf` / `ssl_*` --- ## 示例 ```bash curl -s http://127.0.0.1:15665/api/ping curl -s http://127.0.0.1:15665/api/status curl -s -X POST http://127.0.0.1:15665/api/nginx/install \ -H 'Content-Type: application/json' -d '{}' curl -s -X POST http://127.0.0.1:15665/api/websites \ -H 'Content-Type: application/json' \ -d '{"name":"demo","type":"static","domain":"demo.local"}' curl -s http://127.0.0.1:15665/api/websites ```