# server-config-cli 一个用 [Ink](https://github.com/vadimdemedes/ink) 写的交互式 TUI,用来初始化服务器:zsh + oh-my-zsh + nvm、openssh-server、frp 客户端及其端口穿透配置。 启动后是菜单式界面,没有传统的子命令/flag —— 所有选项、token、端口都在 TUI 里输入。 ## 安装 ```bash npm install npm run build # 必须先打包,bin/server-config.js 会加载 dist/app.mjs npm link # 可选;之后可以直接 server-config 调起 ``` 也可以不 link,直接: ```bash node bin/server-config.js ``` 要求 Node ≥ 18(建议 20+),并且必须在真正的终端里运行(stdin 需要 TTY,否则 Ink 报 "Raw mode is not supported")。 ## 启动后界面 ``` ╭───────────────────────────────────────╮ │ server-config zsh · ssh · frp client │ ╰───────────────────────────────────────╯ Choose an action: ❯ Install zsh + oh-my-zsh + nvm Install OpenSSH server FRP setup ▸ Bootstrap (zsh + ssh + frp) Quit ↑↓ select · Enter confirm · q quit ``` 通用键位: - `↑` `↓` 移动光标,`Enter` 确认 - `Tab` / `↓` 在表单字段间切换,`↑` 回上一项 - `Esc` 返回上一屏(运行中除外) - 在主菜单按 `q` 退出 ## 各动作做什么 ### Install zsh + oh-my-zsh + nvm 会依次执行: - `apt update` + `apt upgrade -y` - 装 `zsh git curl wget` - `chsh -s /bin/zsh` - 从 gitee 镜像装 oh-my-zsh(`RUNZSH=no CHSH=no KEEP_ZSHRC=yes`) - 装 nvm(`v0.40.4`)并 `nvm install --lts`、`nvm alias default lts/*` - 安装 `zsh-autosuggestions` 和 `zsh-syntax-highlighting`(已存在则 `git pull`) - 把 `~/.zshrc` 的 `plugins=(...)` 改成 `git zsh-autosuggestions zsh-syntax-highlighting` 完成后请 `source ~/.zshrc` 或重开终端。 ### Install OpenSSH server `apt install openssh-server -y` + `systemctl enable --now ssh`。 ### FRP setup 进入子菜单: - **Install frp client + service** — 下载 `frp_0.58.1_linux_amd64.tar.gz`,解压、放到 `/opt/frp/frp_0.58.1_linux_amd64/`,写 `frpc.toml` 和 systemd unit,然后 `systemctl enable --now frpc`。需要输入 token,也可以通过 `FRP_TOKEN` 环境变量预填。 - **Init / rewrite frpc.toml** — 仅重写配置(保留已有代理段)。 - **Add proxy** — 表单式输入名字 / 类型 / local IP / local port / remote port,写入的实际 name 会带 8 位随机后缀(例如 `ssh-aaa12312`),避免重名。可选执行后重启 frpc。 - **List / remove proxies** — 选中即生成删除计划,预览后确认执行。 - **Restart frpc** — `systemctl restart frpc`。 ### Bootstrap 按顺序执行 zsh + ssh + frp 三套,token 走同一个输入。 ## 计划预览和执行 任何会改系统的动作都会先停在 "Plan" 屏:列出每一步要做什么(命令或写文件),可以选 **Run now** 或 **Cancel**。 确认运行后进入实时日志屏:每一步显示状态图标(◐ 运行中 / ✓ 成功 / ✗ 失败),底部 12 行滚动展示子进程 stdout/stderr。任何一步失败立刻停止后续步骤。 ## 默认值 - frp 版本:`0.58.1` - 安装目录:`/opt/frp/frp__linux_amd64` - 配置文件:`/frpc.toml` - 服务名:`frpc` - 默认服务端:`81.70.134.9:15443` - 日志:`/var/log/frpc.log`,level `info`,保留 7 天 - `transport.tcpMux = true`,`transport.tls.enable = false` `serverAddr` / `serverPort` / `installDir` 在 FRP 配置表单里都可以改。如果要改更深的配置(log 路径、TLS 等),目前需要直接编辑 `src/lib/tasks.js` 里的 `buildGlobalsFromOptions`。 ## 开发 ```bash npm run build:watch # 文件变了自动 rebuild npm test # 跑 frp-config 解析/渲染的单元测试 npm run check # 对所有手写 .js 做 node --check ``` 代码分三层: - `src/lib/` — 纯逻辑(CJS),没有 Ink/React 依赖:`frp-config.js` 解析渲染,`tasks.js` 输出计划,`runner.js` 执行并发事件。 - `src/screens/` — Ink/React 组件,每个屏一个文件。 - `src/app.jsx` — 入口 + screen stack。 esbuild 把 `src/app.jsx` 打到 `dist/app.mjs`(ESM 输出,因为 Ink 7 / yoga-layout 用了 top-level await)。