Linkora · 灵桥

📌 本文档是 Linkora 部署的唯一规范入口。 历史文档 deployment-guide.md 与 DEPLOY.md 已归档至 docs/archive/,请以本文件为准。

部署指南

本地运行

前置依赖

安装与启动

# 克隆项目
git clone <repo-url> linkora
cd linkora

# 创建虚拟环境并安装依赖
python3 -m venv .venv
source .venv/bin/activate            # Windows: .venv\Scripts\activate
pip install -r requirements.txt

# 复制配置模板并修改
cp config.yaml.example config.yaml
# 必须修改: llm.api_key / llm.base_url

# 钉钉登录(首次)
dws auth login

# 前台运行(带 Web 管理后台)
python main.py --mode web              # 默认端口 8000

常用参数

# 指定运行模式(both / web / worker,默认 both)
python main.py --mode web

# 自定义 Web 端口(不跟端口默认 8000)
python main.py --mode web --web 9000

# 指定数据目录 / 配置文件
python main.py --data-dir /var/lib/linkora --config /etc/linkora/config.yaml

# 仅运行 worker(不开 Web)
python main.py --mode worker

# 测试规则匹配
python main.py --test-rule "在吗"

# 焦点模式:终端只显示 收到的新消息 / AI 回复 / WARNING 及以上,
# 抑制每条消息的链路内部噪声([发送] DWS 返回、防抖、意图识别、工具路由等)
python main.py --mode both --focus

焦点模式(终端降噪)

稳态运行时,一条消息从「轮询发现 → 门控 → LLM → 发送」会产生 15+ 行 INFO 内部 细节([发送] DWS 返回、[防抖] 已缓存消息、[意图识别]、[工具路由]、LLM 请求参数等),把「谁发来什么、AI 回了什么」淹掉。焦点模式在控制台抑制这些 已知噪声模块的 INFO/DEBUG:

# 启动器默认开启焦点模式;关闭:
python scripts/run_linkora.py --no-focus

单进程模式(推荐用于生产)

python scripts/run_linkora.py --single-process

为什么推荐:SQLite 同一时刻只允许一个写者。默认模式下 Web 与后台轮询分属两个 进程,会同时打开同一个数据库文件,跨进程写锁竞争可能表现为日志里持续的 database is locked、消息轮询丢会话、索引写入退化等问题(2026-10-05 生产事故即由 此引发,详见更新日志 v0.6.0)。

单进程让 Web 与后台轮询同驻一个进程、共用同一把写锁,从根上消除跨进程争用, 不改变任何业务行为。停止:

pkill -f run_linkora.py

排查写锁问题时,可先确认是不是多进程部署造成的:进程列表里若同时存在 main.py --mode web 与 --mode worker 两个进程,即为双进程模式。

macOS 后台服务(launchctl)

# 安装并启动
./scripts/install-mac.sh

# 查看状态
launchctl list | grep linkora

# 查看日志
tail -f logs/linkora.log

# 卸载
./scripts/uninstall-mac.sh

Windows 后台服务(nssm)

需要预先安装 nssm:

# 安装并启动
.\scripts\install-win.ps1

# 查看状态
nssm status Linkora

# 卸载
.\scripts\uninstall-win.ps1

Docker 部署

快速启动

docker compose up -d

环境变量

变量 默认值 说明
ENABLE_WEB 0 是否启动 Web 管理后台(1=启用,端口 8000)

数据持久化

Docker Compose 使用以下挂载持久化数据:

注意:容器以非 root 用户 app(uid 1000) 运行。dws 凭证真实目录为 /home/app/.dws(受 DWS_CONFIG_DIR 环境变量控制),与旧文档提及的 /root/.dingtalk 无关;请勿再挂载 /root/.dingtalk。

dws 认证(Docker)

容器内 dws 使用 Device Code Flow 登录:

docker compose exec app dws auth login

按照提示在浏览器中完成授权即可。凭据保存在 ./dingtalk 目录(容器内 /home/app/.dws)中,重启不丢失。

多组织预登录(可选)

如果你需要同时服务多个钉钉组织,可以使用预登录脚本:

# 1. 在 config.yaml 中配置目标组织列表
# target_orgs:
#   - dingxxxxxxxxxxxx
#   - dingyyyyyyyyyyyy

# 2. 运行预登录脚本
python scripts/prelogin_multiple_orgs.py

脚本会逐个组织执行设备流登录,token 持久化到 ~/.dws/profiles.json,后续轮询时自动使用对应组织的认证凭据。

构建镜像

./docker/build.sh
# 或
docker build -t linkora:latest .