AstroResearch/docs/deployment.md
Asfmq cec4b8cf7b feat: Docker 容器化、Cookie 鉴权、Coordinator 编排、FTS5 搜索与 P1-P3 全面收尾
Docker 容器化部署
  - 提供 Mode A (Alpine musl, ~23MB) 和 Mode B (Distroless glibc, ~87MB)
    两种镜像,Docker Compose 一键启动
  - build.rs 支持 SKIP_DASHBOARD_BUILD 跳过前端构建
  - 国内镜像加速 (npm/apt/apk) 通过 USE_MIRRORS build-arg 控制

  安全:Cookie-Based 鉴权系统
  - HttpOnly/SameSite=Strict Cookie 会话管理(24h 过期自动清理)
  - 登录/登出/验证接口 + 中间件注入
  - 前端登录页面 + 退出按钮
  - 三层 CORS:localhost 鉴权 / 全放通 bookmarklet / 受保护路由
  - 书签脚本 fetch 添加 credentials:'include'

  Coordinator 模式 (P2)
  - 4 个 meta-tool (delegate_task/check_task/task_stop/synthesize)
  - WorkerPool + Semaphore 并发控制 + 超时保护
  - 前端协调者模式开关

  Hook 系统:UserPromptSubmit 事件 (P2)
  - 第 13 个生命周期事件,fire-and-forget 审计

  FTS5 全文搜索 (P3)
  - agent_sessions_fts + agent_messages_fts 虚拟表
  - search_history Agent 工具 + /api/search/history HTTP 接口
  - 前端防抖搜索框 + 仅当前会话筛选

  工具加载优化 (P3)
  - defer_loading 延迟加载 (7 个重型工具)
  - is_readonly 只读标记 (9 个查询工具)
  - classifier_summary 工具目录供 LLM 按需判断

  模型回退策略 (P3)
  - LLM_FALLBACK_MODEL 优先回退 + LLM_FALLBACK_CHAIN 链式轮换
  - LlmClient model 改为 Arc<RwLock> 支持运行时切换
  - 连续 3 次过载后自动切换

  压缩记忆桥接 (P3)
  - 压缩丢弃消息 → 子代理提取持久记忆 (extract_memories_from_compaction)

  git2 依赖修复
  - 切换到 vendored-libgit2,消除 OpenSSL 系统依赖
2026-06-23 20:22:06 +08:00

301 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AstroResearch Deployment Guide / 部署指南
AstroResearch 支持两种部署方式:**Docker 容器化部署**(推荐,零依赖)和**传统源码编译部署**。
---
## 1. Docker 部署(推荐)
Docker 部署无需安装 Rust/Node.js 工具链,一键启动。提供两种镜像模式。
### 快速开始
```bash
# 1. 配置环境变量
cp .env.example .env
# 编辑 .env 填入 API Key
# 2. 启动 (Mode A — 推荐日常使用)
docker compose up -d
# 3. 访问
open http://localhost:8000
```
### 两种镜像模式对比
| | Mode A (`Dockerfile`) | Mode B (`Dockerfile.modeB`) |
|---|---|---|
| **镜像大小** | ~23 MB | ~87 MB |
| **基础镜像** | `alpine:3.21` | `distroless/cc-debian12:nonroot` |
| **libc** | musl (静态链接) | glibc (动态链接) |
| **二进制体积** | ~12 MB | ~59 MB |
| **二进制包含** | Rust + C 依赖 | Rust + C + V8 + BoringSSL |
| **运行时依赖** | 无 (静态链接) | `libc` + `libstdc++` + `libgcc_s` (已内置) |
| **空闲内存** | ~8.6 MiB | ~8.7 MiB |
| **Obscura** | 外部 `bin/` bind mount | 编译在二进制内 |
| **容器 Shell** | 有 (`/bin/sh`) | 无 (distroless) |
| **Healthcheck** | `wget` TCP probe | 编排层替代 |
---
### Mode AAlpine 外部 Obscura推荐日常使用
镜像最小23 MBObscura 作为外部二进制通过 bind mount 注入,可独立更新。
**构建:**
```bash
docker build -t astroresearch:latest .
```
**运行:**
```bash
docker run -d --name astro -p 8000:8000 --env-file .env \
-v ./library:/app/library \
-v ./logs:/app/logs \
-v ./skills:/app/skills:ro \
-v ./bin:/app/bin:ro \
astroresearch:latest
```
> `bin/` 目录需包含编译好的 Obscura 二进制文件(`obscura` 和 `obscura-worker`)。
**docker-compose.yml已内置**
```yaml
services:
astroresearch:
build:
context: .
image: astroresearch:latest
container_name: astroresearch
restart: unless-stopped
ports:
- “${PORT:-8000}:8000”
env_file:
- .env
environment:
- LOG_FORMAT=json
- LOG_OUTPUTS=stdout
volumes:
- ./library:/app/library
- ./logs:/app/logs
- ./skills:/app/skills:ro
- ./bin:/app/bin:ro
```
---
### Mode BDistroless 进程内 Obscura全功能单体
Obscura (V8 + BoringSSL) 编译在二进制内,单容器零外部二进制依赖。适合对外交付的一键部署包。
**前置条件:**
```bash
mkdir -p libs
git clone https://github.com/h4ckf0r0day/obscura libs/obscura
```
**构建:**
```bash
docker build -f Dockerfile.modeB -t astroresearch-all:latest .
```
**运行:**
```bash
docker run -d --name astro -p 8000:8000 --env-file .env \
-v ./library:/app/library \
-v ./logs:/app/logs \
-v ./skills:/app/skills:ro \
astroresearch-all:latest
```
> Mode B 基于 [Distroless](https://github.com/GoogleContainerTools/distroless) 构建,无 Shell/包管理器,安全性更高但无法 `docker exec` 进入调试。
---
### 国内网络加速
默认启用镜像加速(`USE_MIRRORS=1`),海外构建可通过 build-arg 禁用:
```bash
docker build --build-arg USE_MIRRORS=0 -t astroresearch:latest .
```
**加速源:**
| 工具 | 镜像 |
|------|------|
| npm | `registry.npmmirror.com` |
| Alpine apk | `mirrors.aliyun.com` |
| Debian apt | `mirrors.ustc.edu.cn` |
---
### 持久化数据卷
| 容器路径 | 说明 | 推荐权限 |
|----------|------|---------|
| `/app/library` | SQLite 数据库 + PDF/HTML 全文 | 读写 |
| `/app/logs` | 应用日志(仅 `LOG_OUTPUTS=file` 时写入) | 读写 |
| `/app/skills` | Agent 技能文件 (SKILL.md) | 只读 (`:ro`) |
| `/app/bin` | Obscura 外部二进制(仅 Mode A | 只读 (`:ro`) |
> **注意**bind mount 目录的宿主权限必须允许容器内用户uid 65532写入。如遇 `Permission denied`,在宿主执行 `chown -R 65532 ./library ./logs`。
---
## 2. 传统源码编译部署
### 系统要求
- **操作系统**Linux / macOS / Windows
- **运行环境**
- Node.js (v18+) 用以构建前端 React 资源
- Rust (1.75+) 用以编译后端 Axum 进程
- SQLite (自动内置,无需单独部署)
### 构建步骤
**步骤 1构建前端**
```bash
cd dashboard
npm install
npm run build
```
产物位于 `dashboard/dist/`
**步骤 2编译后端**
```bash
cd ..
cargo build --release
```
产物位于 `target/release/astroresearch`
**步骤 3可选健康检查工具**
```bash
cargo build --release --bin health_check
```
### 启动
```bash
cp .env.example .env # 编辑填入 API Key
./target/release/astroresearch
# 监听 http://localhost:8000
```
---
## 3. Obscura 两种部署模式
系统集成 `Obscura` 无头浏览器框架,用于绕过 WAF/Cloudflare 反爬。支持两种模式:
### 模式 A外部命令行 (默认)
Obscura 作为独立二进制运行,与主进程隔离。适合常规生产环境。
| 部署方式 | 步骤 |
|----------|------|
| **Docker** | `docker compose up -d`(自动 bind mount `./bin` |
| **源码** | 下载 obscura 到 `bin/`,赋予执行权限后启动 |
二进制安装(源码部署时):
```bash
mkdir -p bin/
# 下载 obscura 和 obscura-worker 到 bin/,赋予执行权限
chmod +x bin/obscura bin/obscura-worker
```
### 模式 B进程内集成
Obscura (V8 + BoringSSL) 编译进二进制,单文件零外部依赖。
| 部署方式 | 构建命令 |
|----------|---------|
| **Docker** | `docker build -f Dockerfile.modeB -t astroresearch-all:latest .` |
| **源码** | `cargo build --release --features obscura-inprocess` |
> 源码编译 Mode B 需先克隆 [Obscura 源码](https://github.com/h4ckf0r0day/obscura) 到 `libs/obscura/`。同时需要 `binutils``nm` + `objcopy`)和 `libclang-dev` 作为构建依赖。
---
## 4. 极致内存与体积优化
对于低配服务器(如 1核512M系统提供 `release-min` 编译配置。
> `release-min` 与 Mode B 可共同启用但效果有限——V8/BoringSSL 静态库占用的 ~50MB 无法被 LTO 消除。追求极致轻量建议用 **Mode A + release-min** 组合。
**优化指标 (Mode A, release-min)**
| 指标 | release | release-min | 降幅 |
|------|---------|-------------|------|
| 二进制大小 | 17.0 MB | 8.3 MB | 51% |
| 启动 RSS | 34.8 MB | 32.9 MB | 5% |
| 虚拟内存 (VSZ) | 1.27 GB | 302 MB | 76% |
| 数据段 (VmData) | 60.1 MB | 26.5 MB | 55% |
```bash
# 源码编译
cargo build --profile release-min
# Docker已默认使用 release-min
docker build -t astroresearch:latest .
```
**限制 Tokio 线程数:**
```bash
PORT=8000 TOKIO_WORKER_THREADS=1 ./astroresearch
```
---
## 5. 环境变量
| 变量名 | 必需 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- |
| `DATABASE_URL` | 否 | `sqlite:///app/library/astro_research.db` | SQLite 连接 URL |
| `ADS_API_KEY` | 是 | - | NASA ADS API Token |
| `LLM_API_KEY` | 是 | - | LLM API Key |
| `LLM_API_BASE` | 否 | `https://api.openai.com/v1` | LLM API 地址 |
| `LLM_MODEL` | 否 | `gpt-4o-mini` | 对话模型 |
| `EMBEDDING_API_KEY` | 否 | 同 `LLM_API_KEY` | Embedding API Key |
| `EMBEDDING_API_BASE` | 否 | 同 `LLM_API_BASE` | Embedding API 地址 |
| `EMBEDDING_MODEL` | 否 | `text-embedding-3-small` | Embedding 模型 |
| `LIBRARY_DIR` | 否 | `/app/library` | 文献馆藏根目录 |
| `SKILLS_DIR` | 否 | `/app/skills` | Agent 技能目录 |
| `LOG_DIR` | 否 | `/app/logs` | 日志目录 |
| `LOG_FORMAT` | 否 | `json` | 日志格式 (`plain` / `json`) |
| `LOG_OUTPUTS` | 否 | `stdout` | 日志输出 (`stdout` / `file`) |
| `PORT` | 否 | `8000` | 监听端口 |
| `AGENT_MAX_STEPS` | 否 | `8` | Agent 最大步数 |
| `AGENT_TOOL_TIMEOUT_SECS` | 否 | `120` | 工具超时 (秒) |
| `QINIU_AK` / `QINIU_SK` | 否 | - | 七牛云存储凭证 |
| `MINERU_API_URL` | 否 | - | MinerU PDF 解析 API |
---
## 6. 健康检查与维护
**Docker 健康检查Mode A**
```bash
docker ps --filter “health=healthy” --filter “name=astroresearch”
```
Mode B (distroless) 无内置 healthcheck可在编排层配置
```yaml
# docker-compose 或 k8s
healthcheck:
test: [“CMD”, “curl”, “-f”, “http://localhost:8000/”]
```
**源码部署健康检查:**
```bash
# 只读扫描
./health_check
# 自动修复
./health_check -- --fix
```
详见 [排障指南 §4.2](troubleshooting.md#42-馆藏文献健康度检查工具-health_check)。