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

12 KiB

Installation

NomiFun has two host modes that share one Rust backend (see Introduction). This page covers all three ways to install it today:

Official pre-built installers are not yet published. Desktop bundles, macOS signing, updater artifacts, Docker, and native Linux service files can be built locally; there is not yet an official public release channel. Until then, every install path below builds from source. See ../contributing/building-and-packaging.md for the current packaging notes.

Prerequisites

You need a working build toolchain regardless of which mode you target. The exact requirements:

Tool Minimum Why Notes
Rust stable, edition 2024 Compile the backend (and the Tauri shell, for desktop). Install via rustup. The workspace pins edition = "2024" and resolver = "3".
Bun ≥ 1.3.13 Frontend package manager + build (and a hard runtime dependency of the agent engine). 1.1.38 has a stdin bug — do not use it.
Tauri CLI v2 Build the desktop shell. Pulled in as a devDependency; no global install needed.
Git any recent Clone, plus skill discovery and some built-in tools.
C/C++ build tools platform-specific rusqlite (bundled), aws-lc-rs, libgit2-sys. Windows: MSVC + WebView2 runtime. macOS: Xcode CLT. Linux: build-essential cmake clang pkg-config perl.

Optional but recommended on the host that runs Nomi (not for building):

  • ripgrep — code-search backend; falls back to grep if missing.
  • node / npm / npx — many user-installed MCP stdio servers launch via npx -y ….

Clone the repo

git clone <your-fork-or-mirror>/nomifun-tauri.git
cd nomifun-tauri

The rest of this page assumes the repository root is your working directory.

Install JS dependencies

bun install

This populates node_modules/ for the workspace and ui/. Re-run it any time package.json or ui/package.json changes.

Desktop app from source

The desktop app is a Tauri 2 shell (apps/desktop, binary nomifun-desktop) that links the backend in-process and starts it on a free localhost port under the desktop TrustLocalToken policy. Its own WebView receives a per-boot local trust secret, so there is no login screen in the desktop window.

Run in development

bun run dev

What this does, end-to-end:

  1. Tauri's beforeDevCommand runs bun run --filter=./ui dev to start the Vite dev server on http://localhost:5173.
  2. cargo compiles nomifun-desktop (and the workspace it depends on).
  3. The shell starts, picks a free port, spawns the embedded backend, and loads the Vite dev URL. Hot-reload works on the renderer side; the backend restarts only when its Rust code changes.

You will see a tracing line like Server listening on 127.0.0.1:54760 in the console — that is the embedded backend. The renderer reads window.__backendPort (injected by the Tauri shell as an init script) so the SPA always knows where to call /api.

nomifun-desktop running in dev with the embedded backend

Build a release binary

bun run build:ui         # build the SPA into ui/dist
bun run build    # tauri build → installers + standalone binary

tauri build produces:

  • A standalone executable under target/release/nomifun-desktop (.exe on Windows).
  • Platform installers under target/release/bundle/.msi/.exe (Windows), .dmg/.app (macOS), .deb/.AppImage (Linux).

bun run build artifacts are suitable for local testing. For distributable macOS builds, configure apps/desktop/signing/.env.signing and use bun run build:signed. Windows signing still requires an external certificate. To test the updater scaffold, use bun run build:updater, which sets bundle.createUpdaterArtifacts to true. The updater endpoint and public key in apps/desktop/tauri.conf.json must be replaced before shipping any update.

Where data lives (desktop)

The desktop app stores its database and runtime files under the per-user application-data directory, joined with Nomi:

OS Default path
Windows %LOCALAPPDATA%\NomiFun\Nomi (e.g. C:\Users\<you>\AppData\Local\NomiFun\Nomi)
macOS ~/Library/Application Support/NomiFun/Nomi
Linux $XDG_DATA_HOME/NomiFun/Nomi (usually ~/.local/share/NomiFun/Nomi)

Override with NOMIFUN_DATA_DIR=<absolute path> before launching — the shell appends /Nomi, so the dir becomes $NOMIFUN_DATA_DIR/Nomi.

Older builds defaulted to <system temp>/nomifun-data/Nomi, where OS temp cleanup could destroy user data. On first launch the app now relocates such a legacy install to the per-user location automatically (one-shot): data is copied, absolute paths inside the database are rewritten, and the old directory is kept as a backup. If the relocation cannot complete, the app starts from the legacy directory and retries on the next launch.

Note: the app's user-facing name is NomiFun everywhere — the bundle product name (apps/desktop/tauri.conf.json), the runtime window title, and release artifacts. The data folder keeps its existing /Nomi suffix for compatibility with current installs. Internal identifiers keep the legacy nomifun name by design (crates, NOMIFUN_* env vars, the com.nomifun.* bundle identifier).

Web server from source

nomifun-web is an axum server that mounts the same backend in-process and serves the built SPA on the same port (default 8787). It is the right path for self-hosting on a LAN, VPN, or VPS.

Build and run

bun install
bun run build:ui       # ui/dist — required before serving in non-dev mode
bun run serve:web            # = cargo run -p nomifun-web

By default the server binds 127.0.0.1:8787 and uses the same per-user data directory as the desktop app (see Where data lives (desktop)):

nomifun-web: embedded backend + SPA on one port
listening on 127.0.0.1:8787  auth=required  dist=../../ui/dist

On a machine that also has the desktop app installed, a bare nomifun-web run opens the desktop app's data directly — an exclusive server.lock guarantees the two backends never run on that directory at the same time.

Open http://127.0.0.1:8787 in a browser. On the very first visit you will be sent to a setup screen — the username and password you type become the initial admin account. After that, login is required for everyone.

First-run admin setup in the browser

Common flags

nomifun-web (defined in apps/web/src/main.rs) accepts both CLI flags and environment variables:

Flag Env var Default Meaning
--host NOMIFUN_WEB_HOST 127.0.0.1 Bind address. Use 0.0.0.0 only when you intend LAN/VPN/public access; pre-seed or complete admin setup first.
--port NOMIFUN_WEB_PORT 8787 Port for both /api and the SPA.
--data-dir NOMIFUN_DATA_DIR per-user app-data dir, same as the desktop default Backend data dir (db / logs / bun cache / agent state). The env value is taken literally (no /Nomi suffix). Use an absolute path in production.
--dist NOMIFUN_WEB_DIST ../../ui/dist SPA static directory. Set this explicitly when running outside the repo root.
--admin-user NOMIFUN_ADMIN_USERNAME admin Username for pre-seeded admin (only honoured before the admin exists).
--admin-password NOMIFUN_ADMIN_PASSWORD (none — interactive first-run setup) Pre-seed the admin password and skip interactive first-run.
--insecure-no-auth NOMIFUN_WEB_INSECURE_NO_AUTH false Danger. Disable authentication entirely (desktop-style local mode). Loopback / trusted private network only.
(env only) NOMIFUN_HTTPS false Set to true when fronted by TLS so cookies get the Secure flag.

Example, opening it up to the LAN with a pre-seeded admin:

nomifun-web \
  --host 0.0.0.0 --port 8787 \
  --data-dir /var/lib/nomifun \
  --dist /opt/nomifun/web \
  --admin-user admin \
  --admin-password "change-me-to-something-strong"

For full deployment guidance — systemd unit, reverse-proxy, and security notes — see ../guides/web-server-deployment.md.

Docker / Docker Compose

The repository ships a multi-stage Dockerfile and a docker-compose.yml that produce a headless (no GUI) image: SPA + nomifun-web + bun on debian:bookworm-slim.

Quick start with Compose

From the repo root:

docker compose up -d --build
# then open http://<server-ip>:8787

The service is configured with restart: unless-stopped so installing it is enabling it on boot. Persistent state (SQLite database, logs, bun cache, agent state) lives in the named volume nomifun-data mounted at /data inside the container.

The image's defaults are tuned for container life:

NOMIFUN_WEB_HOST=0.0.0.0
NOMIFUN_WEB_PORT=8787
NOMIFUN_DATA_DIR=/data
NOMIFUN_WEB_DIST=/opt/nomifun/web
SHELL=/bin/bash

Authentication is on, but first-run setup can be claimed by the first browser that reaches the service. Pre-seed the admin or complete setup on a trusted network before publishing port 8787 broadly. For anything reachable from the internet, put TLS in front of it — the bundled Caddyfile and the commented-out caddy service in docker-compose.yml are the recommended path. Set NOMIFUN_HTTPS=true on the nomifun service when you do, so the session cookie gains the Secure flag.

The first browser visit otherwise wins the admin account; pre-seeding closes that race window:

# docker-compose.yml — under services.nomifun
environment:
  NOMIFUN_ADMIN_USERNAME: admin
  NOMIFUN_ADMIN_PASSWORD: "change-me-to-something-strong"
  NOMIFUN_HTTPS: "true"   # only when behind a TLS proxy

Speeding up Rust builds

The Rust stage uses BuildKit cache mounts (/usr/local/cargo/registry and /src/target), so a one-line source change recompiles in seconds. To use a mirror for the cargo registry (e.g. on slow links):

docker build --build-arg CARGO_REGISTRY_MIRROR=https://rsproxy.cn/index/ .

For the long-form deployment guide (TLS, reverse-proxy patterns, systemd unit, security caveats) see ../guides/web-server-deployment.md.

Verifying your install

A 30-second smoke test you can run after either path:

# Rust workspace compiles cleanly
cargo check --workspace

# All three binaries build
cargo build --workspace --bins
# → target/(debug|release)/{nomicore, nomifun-web, nomifun-desktop}

# Web host responds with the SPA + auth status
curl -sS http://127.0.0.1:8787/                | head -c 200
curl -sS http://127.0.0.1:8787/api/auth/status
# → 200 {"success":true,"needs_setup":..., "user_count":...}

If you see nomifun-web: embedded backend + SPA on one port in the logs and /api/auth/status returns JSON, the backend is up and the SPA is being served from the same port.

What's next