---
title: "环境变量"
description: "实例环境变量的完整清单：模式与端口、空间与元数据库、语义搜索、Docker 镜像。"
---

# 环境变量

Notarium 通过环境变量进行配置。默认值开箱即用——本地运行无需填写任何内容：把 `.env.example` 复制成 `.env`，只改你确实需要的那几行即可。Docker 栈会把 `.env` 原样传入容器（值不会被固化进镜像），因此同一个文件既描述你的本地实例，也描述你的生产实例。

```bash
cp .env.example .env      # 默认值即可用——只改你需要的
```

下面是完整参考。部分变量直接写在 `.env.example` 里；另一部分（搜索的精细调优）在代码中带有默认值，并未在示例文件中列出——这些会单独标注。

## 核心

基础项：端口、认证模式，以及元数据库和空间的位置。

| 变量 | 用途 | 默认值 | 示例 |
|---|---|---|---|
| `DATA_DIR` | 唯一的数据旋钮：其余一切都由这个根目录派生而来——元数据库、索引、笔记、产物。未设置 → 采用一个合理的默认值。 | `/data`（Docker）；`~/.local/share/notarium`（宿主机） | `DATA_DIR=/srv/notarium` |
| `PORT` | 后端监听的端口；单个 Fastify 监听器同时服务 `/api`、`/mcp` 和 SPA 的静态资源。 | `3000` | `PORT=3000` |
| `AUTH_MODE` | 认证模式：`password`（登录加上首次运行的设置界面，需要元数据库）或 `none`（面向桌面/开发/可信内网的单一全权限主体，无登录界面）。 | `password` | `AUTH_MODE=none` |
| `META_DB_URL` | 元数据库：身份、修订日志、空间注册表、认证、项目。默认是 `DATA_DIR` 下的 sqlite，因此 `password` 模式无需配置即可工作。可选：仅当你要把元数据状态迁移到外部 Postgres（共享状态、HA）时才设置。 | `sqlite:<DATA_DIR>/meta.db` | `META_DB_URL=postgres://user:pass@db:5432/notarium` |
| `SPACES_ROOT` | 每个空间即一个文件夹的根目录；设置后即可在运行时从 UI 创建空间。可选：默认为 `<DATA_DIR>/spaces`，仅当你的笔记位于数据根目录之外时才设置。 | `<DATA_DIR>/spaces` | `SPACES_ROOT=/mnt/notes` |
| `SPACES_CONFIG` | 显式的空间拓扑：内联 JSON 或指向某个 JSON 文件的路径。会覆盖单空间相关变量。 | 未设置 | `SPACES_CONFIG=/data/spaces.json` |
| `ENGINE_DATA_DIR` | 引擎存放派生索引的位置——每个空间一个文件。文件名沿用空间的文件夹名，空间改名时也不会跟着变。删除该目录 → 启动时重建索引；索引是可恢复的。可选：默认为 `<DATA_DIR>/engine`，设置它可把索引挪到另一块磁盘。 | `<DATA_DIR>/engine` | `ENGINE_DATA_DIR=/mnt/ssd/engine` |
| `JOBS_DATA_DIR` | 任务目录：异步导出的产物（派生数据，按 TTL 清理）**以及**未完成导入所上传的文件——后者与自己的任务同生共死，因此需要纳入备份。可选：默认为 `<DATA_DIR>/jobs`，设置它可挪到另一块磁盘。 | `<DATA_DIR>/jobs` | `JOBS_DATA_DIR=/mnt/ssd/jobs` |
| `SPACE_IDLE_EVICT_SECONDS` | 逐出空闲空间的读模型。设为 `0` 表示保持热态；拥有活跃 SSE 连接的空间永不被逐出。 | `0` | `SPACE_IDLE_EVICT_SECONDS=900` |
| `SYNC_POLL_SECONDS` | 轮询磁盘上外部改动的间隔（每次轮询都是一次完整的空间重扫）。设为 `0` 关闭轮询。对于无法监听的挂载（网络卷、内存盘），实际间隔上限为 60 秒。 | `120` | `SYNC_POLL_SECONDS=0` |
| `PUBLIC_BASE_URL` | 实例在反向代理之后的规范外部地址——用于 MCP 连接器的 OAuth 元数据。不设置时，地址将从代理转发的请求头推导。 | 未设置 | `PUBLIC_BASE_URL=https://notes.example.com` |
| `TRUST_PROXY` | 以逗号分隔的**紧邻的上游**代理 IP/CIDR 列表——据此推导出真实的客户端 IP，用于登录限流和放行新的 OAuth 客户端。不设置即采用安全默认：`X-Forwarded-For` 不影响限流。布尔值、跳数、具名网段以及全地址网段（`/0`）会在启动时被拒绝。 | 未设置 | `TRUST_PROXY=172.18.0.0/16` |

> [!note] 元数据库 vs. 文件
> 磁盘上存放着两种不同的东西。`SPACES_ROOT` 是 **Markdown 事实来源**（你的笔记，每个空间一个文件夹）。`META_DB_URL` 是元数据库：无法从文件派生出来的部分（用户、访问权限、版本历史）。详见[自托管](/docs/self-hosting/)一节。

## 单空间（裸宿主机，无 Docker）

用于在不使用 `SPACES_CONFIG` 且不使用 `SPACES_ROOT` 的情况下运行单个空间（例如无 Docker 的本地裸运行）。

| 变量 | 用途 | 默认值 | 示例 |
|---|---|---|---|
| `ENGINE` | 单空间的引擎。唯一取值是 `notarium`；可以不设置。 | `notarium` | `ENGINE=notarium` |
| `NOTES_DIR` | 单空间笔记文件夹的绝对路径（单空间模式）。 | 未设置 | `NOTES_DIR=/home/me/notes` |

## 语义搜索

词法全文搜索（FTS）始终可用，无需任何配置。语义（向量）搜索和混合搜索**需自行开启**：一套沉重的原生栈（`onnxruntime` + `sqlite-vec`，磁盘占用约 660 MB）外加 bge-m3 嵌入模型（磁盘占用约 600 MB，内存数百 MB）。下面这些变量在代码中带有默认值，并未写入 `.env.example`。

| 变量 | 用途 | 默认值 | 示例 |
|---|---|---|---|
| `VECTOR_SEARCH` | `on`/`off`——开启语义搜索和混合融合。原生栈缺失时，`on` 会回退到全文搜索——不报错。 | `on`（代码），`off`（发布镜像） | `VECTOR_SEARCH=on` |
| `EMBED_MODEL` | 嵌入模型的 id（transformers.js/ONNX）。需与 `EMBED_DIMENSIONS` **一起**设置。 | `Xenova/bge-m3` | `EMBED_MODEL=Xenova/multilingual-e5-small` |
| `EMBED_DIMENSIONS` | 向量维度；**必须**与模型匹配（bge-m3 为 1024，e5-small 为 384）。不匹配时直接失败（fail closed）：该笔记仍仅用 FTS。 | `1024` | `EMBED_DIMENSIONS=384` |
| `EMBED_DTYPE` | 模型量化：`fp32` / `fp16` / `q8` / `q4`。 | `q8` | `EMBED_DTYPE=fp16` |
| `EMBED_THREADS` | 每个后台索引工作线程的 ONNX intra-op 线程数（一个由 `EMBED_WORKERS` 个工作线程组成的池）。 | 每个工作线程 `1`（无池回退时——核数的一半） | `EMBED_THREADS=2` |
| `EMBED_WORKERS` | 嵌入 `worker_threads` 池的大小 = 后台索引在多核上的并行度。每个工作线程各持有一份模型副本（这会影响内存）。 | `max(1, min(核数−2, 4))` | `EMBED_WORKERS=8` |
| `EMBED_QUERY_PREFIX` / `EMBED_PASSAGE_PREFIX` | 非对称模型（e5）的前缀。对于对称的 bge-m3 请**保持不设置**——否则质量会以你察觉不到的方式下降。 | 未设置 | `EMBED_QUERY_PREFIX="query: "` |
| `EMBED_CPU_MEM_ARENA` | `on`/`off`。`off` 将 bge-m3 的占用稳定压在约 1.9 GB 内存——用于在内存紧张、无 swap 的机器上防 OOM（设为 `on` 时 arena 可能悄悄涨到数 GB）。 | `on` | `EMBED_CPU_MEM_ARENA=off` |
| `GRAPH_BOOST` | `on`/`off`——第三条 RRF 通道（沿链接的图谱加权，1 跳维基链接）。当 `VECTOR_SEARCH=off` 时不生效。 | `off` | `GRAPH_BOOST=on` |

> [!warning] 两个相互独立的开关
> 要让语义在本地生效，你需要**两者都满足**：原生栈**已安装**（`make deps-vector`；默认的 `make deps` 不安装它，发布镜像则始终带上它）**且** `VECTOR_SEARCH=on`。若原生栈缺失，`on` 会回退到词法全文搜索——不报错。详见[搜索](/docs/concepts/search/)和[搜索设置](/docs/self-hosting/search-setup/)两节。

## 备份与恢复

内置的 `backup`、`backup verify` 和 `restore` 命令无需任何配置即可使用。下面这些变量只在容器根目录以只读方式挂载、或数据量明显超出常规时才用得上。详见[备份与恢复](/docs/self-hosting/backup/)。

| 变量 | 用途 | 默认值 | 示例 |
|---|---|---|---|
| `NOTARIUM_BACKUP_TMPDIR` | 存放备份、校验与恢复过程中间文件的目录。若容器根目录是只读的，或 `/tmp` 空间吃紧，就设置它：流式备份可能临时需要放下归档本身，外加两份展开的中间产物。 | `/tmp` | `NOTARIUM_BACKUP_TMPDIR=/mnt/scratch` |
| `NOTARIUM_BACKUP_MAX_BYTES` | 体积上限——压缩后的输入和展开后的有效载荷都受它约束。用于防 zip 炸弹；只有受信任的大型部署才会调高。 | 64 GiB | `NOTARIUM_BACKUP_MAX_BYTES=137438953472` |
| `NOTARIUM_BACKUP_MAX_ENTRIES` | 归档中条目数量的上限。 | `1000000` | `NOTARIUM_BACKUP_MAX_ENTRIES=2000000` |
| `NOTARIUM_BACKUP_MAX_METADATA_BYTES` | 针对文件名、ZIP 内部结构和 `manifest.json` 的单独内存上限。 | 32 MiB | `NOTARIUM_BACKUP_MAX_METADATA_BYTES=67108864` |

## Docker 与构建

| 变量 | 用途 | 默认值 | 示例 |
|---|---|---|---|
| `IMAGE` / `TAG` | 供 `docker compose` / `make up` 使用的镜像引用。主要安装路径是公共镜像 `docouno/notarium:latest`；覆盖该坐标即可使用你自己的镜像仓库或某个特定标签。 | `docouno/notarium:latest` | `IMAGE=docouno/notarium` `TAG=latest` |
| `GIT_SHA` / `BUILD_TIME` | 构建参数；会内联进 `GET /api/about` 和 **Settings → About** 标签页。不提供时——`null`。 | 空 | `GIT_SHA=$(git rev-parse --short HEAD)` |

> [!important] 镜像与从源码构建
> `docouno/notarium:latest` 是公共镜像和主要安装路径；`IMAGE` / `TAG` 决定 `docker compose` / `make up` 会拉取哪个镜像。如果镜像尚未从镜像仓库拉取——就从主代码仓库的源码构建：`make up`（行为完全一致）。

## 另见

- [自托管配置](/docs/self-hosting/configuration/) — 安装、数据卷、生产环境配置。
- [搜索](/docs/concepts/search/) — 词法、语义、混合融合，以及无报错回退到全文搜索。
- [键盘快捷键参考](/docs/reference/keyboard-shortcuts/) — 布局与预设。
