Files
freedak f7a720204a Update: 将子项目从 submodule 转为完整内容
- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用
- 添加所有子项目的完整源代码
- 保留原始 .git 为 .git.bak 备份
2026-07-04 19:20:46 +08:00

7.1 KiB

在无 UI 的 Linux 服务器上部署 NomiFun WebUI

本目录是 headless(无图形界面) 部署产物。服务器上不要装 Tauri 桌面包(.deb/.AppImage 需要图形会话);要跑的是 nomifun-web —— 一个纯 axum 的 HTTP/WS 服务,后端 in-process + 同端口托管前端 SPA,零 GUI 依赖,可在没有显示器的服务器上运行。

访问与认证模型(重要)

  • nomifun-web 默认要求登录。 第一次用浏览器打开时,登录框里你输入的用户名 + 密码就成为初始管理员账号(首启 setup,一次性)。之后该端点关闭(再调返回 409),只能用这套凭据登录。
  • 桌面版(Tauri)不受影响,仍是本机免认证。
  • 默认建议先只监听 127.0.0.1,完成首启管理员设置或预置 NOMIFUN_ADMIN_PASSWORD 后,再显式改为 0.0.0.0 暴露给 LAN/VPN。 面向公网请务必在前面加 TLS(见下文 Caddy)。
  • 可选:设置 NOMIFUN_ADMIN_PASSWORD 在启动时预置管理员,跳过交互式首启(适合自动化部署 / 想关闭首启竞态窗口的场景)。

方式一:Docker(推荐)

仓库根目录已带 Dockerfiledocker-compose.ymlCaddyfile

# 在仓库根目录
docker compose up -d --build
# 默认发布 8787;首次访问会创建管理员。公开暴露前建议预置管理员或先在可信网络完成 setup。

restart: unless-stopped 已让它开机自启 + 崩溃自拉——装好就等于"自动开启 webui"。数据(SQLite、日志、bun 运行时缓存、agent 状态)落在命名卷 nomifun-data:/data

查看启动是否就绪:

docker compose logs -f nomifun   # 看到 "nomifun-web: embedded backend + SPA on one port" 即 OK

加 TLS(公网必做)

docker-compose.yml 里有一段注释掉的 caddy 服务。启用步骤:

  1. 编辑 Caddyfile,把 your.domain.com 换成你的域名;
  2. nomifunenvironment 里加 NOMIFUN_HTTPS: "true"(让会话 cookie 带 Secure);
  3. nomifunports: ["8787:8787"] 改成 expose: ["8787"](只让 Caddy 对外);
  4. 取消 caddy 服务和 caddy-* 卷的注释;
  5. docker compose up -d

Caddy 会自动签 HTTPS 证书,WebSocket(/ws)自动透传,无需额外配置。应用自带登录,所以 Caddy 不需要再配 basic_auth


方式二:原生二进制 + systemd(不想用 Docker)

需要一台 Linux 构建机(Windows 交叉编译这堆 C 依赖很痛,不建议;也可直接从 Docker 镜像里 docker cp 出二进制)。

1) 构建产物

bun install
bun run build:ui                      # → ui/dist(SPA,~21MB)
cargo build --release -p nomifun-web  # → target/release/nomifun-web

2) 部署布局

/opt/nomifun/nomifun-web      # 二进制
/opt/nomifun/web/             # = ui/dist 的内容
/var/lib/nomifun/             # data 目录(systemd StateDirectory 自动创建)
sudo useradd --system --home /var/lib/nomifun --shell /usr/sbin/nologin nomifun
sudo mkdir -p /opt/nomifun/web
sudo cp target/release/nomifun-web /opt/nomifun/
sudo cp -r ui/dist/.            /opt/nomifun/web/

⚠️ bun ≥ 1.3.13 必须在「系统」PATH 上nomifun 是 nologin 账户,装到某人 ~/.bun/bin/ 里它读不到(systemd 服务也不会用你的 ~/.bun)。可靠做法二选一:

  • 系统级安装:curl -fsSL https://bun.sh/install | bash,然后 sudo install ~/.bun/bin/bun /usr/local/bin/bun(或用包管理器 / npm i -g bun);
  • 编进二进制(免 PATH 依赖):构建时 NOMIFUN_EMBED_BUN=1 cargo build --release -p nomifun-web,bun 会嵌入并在 data 目录自解压(需构建环境能取到 bun)。

校验:sudo -u nomifun -s -- which bun 必须返回路径,否则 agent 首次 spawn 才暴露失败、错误隐晦。

3) 安装并开机自启

sudo cp packaging/linux/nomifun-web.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now nomifun-web      # 开机自启 + 立即启动 = 自动开 webui
sudo systemctl status nomifun-web

同样建议在前面摆一个 Caddy/nginx 做 TLS,并在 unit 里设 Environment=NOMIFUN_HTTPS=true

⚠️ unit 里 Environment=NOMIFUN_DATA_DIR=/var/lib/nomifun 必须与 StateDirectory=nomifun 保持一致。若你改 unit(比如注释掉 User/Group 改用 root)时不慎删掉那行,数据会悄悄落到服务用户的按用户目录($XDG_DATA_HOME/NomiFun/Nomi,通常是 ~nomifun/.local/share/NomiFun/Nomi),与 systemd 托管的 /var/lib/nomifun 脱钩。


启动参数 / 环境变量

参数 环境变量 默认 说明
--host NOMIFUN_WEB_HOST 127.0.0.1 监听地址。0.0.0.0 会对 LAN/VPN/公网可达;请先完成管理员设置或预置密码,公网必须放在 TLS 之后
--port NOMIFUN_WEB_PORT 8787 同时服务 API、/ws、SPA 的端口
--data-dir NOMIFUN_DATA_DIR 按用户目录 数据目录(db / 日志 / bun 缓存 / agent 状态)。默认是服务用户的按用户目录(Linux 为 $XDG_DATA_HOME/NomiFun/Nomi);生产请显式指定绝对路径
--dist NOMIFUN_WEB_DIST ../../ui/dist SPA 静态目录。部署时必须显式指定
NOMIFUN_HTTPS false true 时会话/CSRF cookie 带 Secure(仅在 TLS 后用)
--admin-user NOMIFUN_ADMIN_USERNAME admin 预置管理员用户名(仅预置时用)
--admin-password NOMIFUN_ADMIN_PASSWORD 设了就在启动时预置管理员、跳过交互首启
--insecure-no-auth NOMIFUN_WEB_INSECURE_NO_AUTH false ⚠️ 关闭认证(桌面式 no-auth)。只在仅 loopback / 受信私网可达时用

直接命令行示例:

nomifun-web --host 127.0.0.1 --port 8787 \
  --data-dir /var/lib/nomifun --dist /opt/nomifun/web

Linux 运行时依赖

依赖 必需性 说明
glibc + ca-certificates 必需 sqlite 静态链接、TLS 用 rustls,无需 openssl / libsqlite
bun ≥ 1.3.13 必需 agent 执行;1.1.38 有 stdin bug。Docker 镜像里已含
node / npm / npx 推荐 用户启用的 MCP stdio server(npx -y …)
git 推荐 skill 发现、部分内置工具
ripgrep(rg) 推荐 代码搜索后端(缺则退化到 grep)
DISPLAY / X11 / WebView 不需要 nomifun-web 零 GUI 依赖,纯 headless

安全须知

  • 务必走 TLS(公网):cookie 与登录凭据明文传输会被嗅探。TLS 后记得 NOMIFUN_HTTPS=true
  • 首启竞态:从服务起来到你完成首启 setup 之间,理论上谁先访问谁就能占下管理员账号。要彻底关掉这个窗口,用 NOMIFUN_ADMIN_PASSWORD 预置;或先监听 127.0.0.1 / 内网 / 隧道完成首启,再改为 0.0.0.0
  • --insecure-no-auth 谨慎:它把认证完全关掉(任何能连端口的人 = 特权用户,可执行 shell / 读写文件)。只在纯 loopback 或完全受信的私网用。
  • 后端有终端 / 文件 / agent 能力,等价于"远程运维 = 远程代码执行(对你自己)"——这正是产品本意,但也因此认证 + TLS 是底线