📌 本文档是 Linkora 部署的唯一规范入口。 历史文档
deployment-guide.md与DEPLOY.md已归档至docs/archive/,请以本文件为准。
dws auth login 完成认证)# 克隆项目
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:
✅ 收到 %s 的新消息、LLM 回复: %s、启动/关闭横幅;logs/linkora.log 文件日志与 Web「实时日志」页仍是全量,排障直接
翻文件;周期性统计(展示摘要评估、轮询统计)已降为 DEBUG,需要时把
config.yaml 的 logging.level 设为 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 两个进程,即为双进程模式。
# 安装并启动
./scripts/install-mac.sh
# 查看状态
launchctl list | grep linkora
# 查看日志
tail -f logs/linkora.log
# 卸载
./scripts/uninstall-mac.sh
需要预先安装 nssm:
# 安装并启动
.\scripts\install-win.ps1
# 查看状态
nssm status Linkora
# 卸载
.\scripts\uninstall-win.ps1
docker compose up -d
| 变量 | 默认值 | 说明 |
|---|---|---|
ENABLE_WEB |
0 |
是否启动 Web 管理后台(1=启用,端口 8000) |
Docker Compose 使用以下挂载持久化数据:
./data — SQLite 数据库、备份./logs — 日志./dingtalk — dws 认证凭据(容器内 /home/app/.dws,非 root 用户 app 持有)./config.yaml — 配置文件(只读挂载)注意:容器以非 root 用户
app(uid 1000) 运行。dws 凭证真实目录为/home/app/.dws(受DWS_CONFIG_DIR环境变量控制),与旧文档提及的/root/.dingtalk无关;请勿再挂载/root/.dingtalk。
容器内 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 .