# Installation / 部署安装指南

本文件记录当前仓库的真实安装和部署方式。它面向一台新的 Linux 机器，目标是跑起完整系统：

- React 前端：默认 `http://localhost:3000`
- FastAPI 后端：默认 `http://localhost:8000`
- PostgreSQL：项目、帧、模板、标注、任务元数据
- Redis：Celery broker/result backend 与进度 pub/sub
- MinIO：视频、DICOM、拆帧图片等对象存储
- Celery worker：执行视频/DICOM 拆帧等后台任务
- SAM 2.1：当前产品启用 tiny/small/base+/large；SAM 3 源码保留但产品入口禁用，正常部署不需要安装 SAM 3

---

## 1. 前置条件

推荐环境：

| 项 | 建议 |
|----|------|
| OS | Ubuntu 22.04 LTS 或相近 Linux |
| Python | 3.11 |
| Node.js | 22.x |
| 数据库 | PostgreSQL 14+ |
| 缓存/队列 | Redis 6+ |
| 对象存储 | MinIO |
| 视频处理 | FFmpeg |
| GPU | NVIDIA GPU + CUDA，用于 SAM 2.1 推理；无 GPU 时可 CPU 运行但会很慢 |

安装系统依赖：

```bash
sudo apt update
sudo apt install -y \
  postgresql postgresql-contrib \
  redis-server \
  ffmpeg \
  libpq-dev build-essential curl ca-certificates gnupg wget
```

安装 MinIO：

```bash
cd /tmp
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/
mkdir -p ~/minio_data
```

---

## 2. 获取代码

```bash
cd ~/Desktop
git clone <your-gitea-or-git-url> Seg_Server
cd Seg_Server
```

如果已经有仓库，进入项目根目录即可：

```bash
cd /home/wkmgc/Desktop/Seg_Server
```

后续命令默认在项目根目录执行，除非特别说明。

---

## 3. 配置 PostgreSQL

默认后端配置来自 `backend/config.py`：

```text
postgresql://seguser:segpass123@localhost:5432/segserver
```

创建数据库和用户：

```bash
sudo systemctl start postgresql

sudo -u postgres psql -c "CREATE DATABASE segserver;"
sudo -u postgres psql -c "CREATE USER seguser WITH PASSWORD 'segpass123';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE segserver TO seguser;"
sudo -u postgres psql -d segserver -c "GRANT ALL ON SCHEMA public TO seguser;"
sudo -u postgres psql -c "ALTER DATABASE segserver OWNER TO seguser;"
```

验收：

```bash
pg_isready
psql "postgresql://seguser:segpass123@localhost:5432/segserver" -c "select 1;"
```

---

## 4. 启动 Redis 和 MinIO

Redis：

```bash
sudo systemctl start redis-server
redis-cli ping
```

MinIO：

```bash
nohup minio server ~/minio_data --console-address :9001 > /tmp/minio.log 2>&1 &
curl http://localhost:9000/minio/health/live
```

默认 MinIO 账号密码是：

```text
minioadmin / minioadmin
```

后端启动时会检查并创建 bucket：

```text
seg-media
```

---

## 5. 安装后端 Python 环境

推荐使用 Conda：

```bash
conda create -n seg_server python=3.11 -y
conda activate seg_server
```

安装 PyTorch。根据机器 CUDA 版本选择合适 wheel。示例：

```bash
# CUDA 12.4 示例
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

# 无 GPU / CPU 示例
# pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
```

安装后端依赖：

```bash
cd backend
pip install -r requirements.txt
cd ..
```

确认关键包：

```bash
python - <<'PY'
import fastapi, sqlalchemy, redis, celery, minio, torch
print("torch:", torch.__version__, "cuda:", torch.cuda.is_available())
PY
```

---

## 6. 配置后端环境变量

后端从 `backend/.env` 读取配置；该文件被 `.gitignore` 忽略，不要提交真实密码或本机路径。

创建 `backend/.env`：

```bash
cat > backend/.env <<'EOF'
db_url=postgresql://seguser:segpass123@localhost:5432/segserver
redis_url=redis://localhost:6379/0

minio_endpoint=localhost:9000
minio_access_key=minioadmin
minio_secret_key=minioadmin
minio_secure=false

sam_default_model=sam2.1_hiera_tiny
sam_model_path=/home/wkmgc/Desktop/Seg_Server/models/sam2.1_hiera_tiny.pt
sam_model_config=configs/sam2.1/sam2.1_hiera_t.yaml

app_env=development
cors_origins=["http://localhost:3000","http://127.0.0.1:3000"]
jwt_secret_key=change-this-to-a-long-random-production-secret
access_token_expire_minutes=1440
default_admin_username=admin
default_admin_password=123456
demo_video_path=/home/wkmgc/Desktop/Seg_Server/Data_MyVideo_1.mp4
demo_dicom_dir=/home/wkmgc/Desktop/Seg_Server/2024_2_5_王芳/※2F458C45CFAA4C7CB76A39AA2BFE436B
EOF
```

如果前端通过局域网 IP 访问，例如 `http://192.168.3.11:3000`，需要把该地址加入 `cors_origins`，同时前端也要配置 API 地址。

---

## 7. 准备 SAM 2.1 权重

当前产品入口只暴露 SAM 2.1 变体：

- `sam2.1_hiera_tiny`
- `sam2.1_hiera_small`
- `sam2.1_hiera_base_plus`
- `sam2.1_hiera_large`

下载脚本：

```bash
cd backend
python download_sam2.py
cd ..
```

脚本默认下载到：

```text
/home/wkmgc/Desktop/Seg_Server/models/
```

推荐文件名：

```text
models/sam2.1_hiera_tiny.pt
models/sam2.1_hiera_small.pt
models/sam2.1_hiera_base_plus.pt
models/sam2.1_hiera_large.pt
```

可以只部署 tiny；前端会显示四个选项，但只有本地存在 checkpoint 的模型会显示可用。

注意：SAM 3 相关脚本和源码是历史保留。当前前端入口隐藏 SAM 3，后端 registry 不暴露 `sam3`，正常部署不需要下载 SAM 3 权重，也不要把 Hugging Face token 写进项目文件。

---

## 8. 安装前端依赖

```bash
npm install
```

如需指定前端访问的后端地址，在项目根目录创建 `.env`：

```bash
cat > .env <<'EOF'
VITE_API_BASE_URL=http://localhost:8000
VITE_WS_PROGRESS_URL=ws://localhost:8000/ws/progress
EOF
```

如果不设置，前端会按当前浏览器 hostname 推导：

```text
http://<browser-host>:8000
ws://<browser-host>:8000/ws/progress
```

---

## 9. 手动启动所有服务

开 4 个终端分别启动。

终端 A：FastAPI 后端

```bash
conda activate seg_server
cd /home/wkmgc/Desktop/Seg_Server/backend
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```

终端 B：Celery worker

```bash
conda activate seg_server
cd /home/wkmgc/Desktop/Seg_Server/backend
celery -A celery_app:celery_app worker --loglevel=info --pool=solo --concurrency=1
```

终端 C：前端开发服务

```bash
cd /home/wkmgc/Desktop/Seg_Server
npm run dev
```

终端 D：确认基础设施

```bash
pg_isready
redis-cli ping
curl http://localhost:9000/minio/health/live
```

访问：

| 服务 | 地址 |
|------|------|
| 前端 | `http://localhost:3000` |
| FastAPI Docs | `http://localhost:8000/docs` |
| Health | `http://localhost:8000/health` |
| MinIO Console | `http://localhost:9001` |

默认开发登录：

```text
admin / 123456
```

首次启动会自动创建默认管理员，密码以哈希形式写入 `users` 表；登录返回签名 JWT，业务接口会校验 `Authorization: Bearer <token>`。生产环境必须修改 `jwt_secret_key` 和默认管理员密码。

默认管理员登录后会看到“用户管理”后台，可新增用户、停用/启用用户、修改角色、重置密码、删除无项目用户并查看登录与用户管理审计日志。角色分为 `admin`、`annotator`、`viewer`：`admin/annotator` 可以执行写入类业务操作，`viewer` 只读。演示部署可在该后台使用“恢复演示出厂设置”，二次确认后只保留默认 admin、演示视频项目和一个已按文件名自然顺序生成帧的演示 DICOM 项目；视频来自 `demo_video_path`，DICOM 序列来自 `demo_dicom_dir`。

---

## 10. 一键启动脚本

项目根目录有 `start_services.sh`：

```bash
chmod +x start_services.sh
./start_services.sh
```

脚本会检查/启动：

```text
PostgreSQL -> Redis -> MinIO -> FastAPI -> Celery worker -> 前端
```

使用前必须检查脚本里的本机路径和 sudo 逻辑：

- `PROJECT_DIR="/home/wkmgc/Desktop/Seg_Server"`
- `CONDA_ENV="seg_server"`
- MinIO 数据目录 `/home/wkmgc/minio_data`
- 脚本里包含本机 sudo 密码写法，迁移机器时应移除或改成安全的 systemd/service 管理方式

### 10.1 开发重启速查

本地开发时不要靠猜。不同服务的热更新行为如下：

| 改动类型 | 是否需要重启 | 原因 |
|----------|--------------|------|
| 前端 `src/`、`server.ts` | 通常不需要 | `npm run dev` 使用 Vite/tsx，前端会热更新 |
| 前端依赖、`.env`、`vite.config.ts` | 需要重启前端 | 依赖和环境变量只在进程启动时读取 |
| FastAPI 路由/普通后端代码 | 需要重启后端 | 开发重启脚本用独立后台进程运行后端；显式重启可以保证接口和运行态一致 |
| `backend/.env`、模型路径、依赖安装 | 需要重启后端 | 配置和依赖在进程启动时生效 |
| Celery 任务、拆帧、自动传播、SAM runner | 必须重启 Celery worker | worker 不是 `uvicorn --reload` 的子进程，不会自动加载代码改动 |

推荐使用项目根目录的开发重启脚本：

```bash
cd /home/wkmgc/Desktop/Seg_Server
./restart_dev_services.sh
```

该脚本会：

```text
检查 PostgreSQL/Redis/MinIO -> 停止旧 FastAPI/Celery/前端 -> 用独立后台进程启动 FastAPI/Celery/前端 -> 检查 3000/8000
```

脚本通过 `setsid` 启动应用层服务，脚本退出后服务会继续运行；pid 文件默认位于 `/tmp/seg_server_*.pid`，日志默认位于 `/tmp/seg_server_*.log`。

默认日志：

```text
/tmp/seg_server_fastapi.log
/tmp/seg_server_celery.log
/tmp/seg_server_frontend.log
/tmp/seg_server_minio.log
```

如果只想手动重启应用层服务，可以使用：

```bash
cd /home/wkmgc/Desktop/Seg_Server

# 停止旧进程
pkill -f "uvicorn main:app" || true
pkill -f "celery -A celery_app:celery_app worker" || true
pkill -f "/home/wkmgc/Desktop/Seg_Server/node_modules/.bin/tsx server.ts" || true
pkill -f "npm run dev" || true

# 启动后端和 worker
cd /home/wkmgc/Desktop/Seg_Server/backend
setsid ~/miniconda3/bin/conda run -n seg_server uvicorn main:app --host 0.0.0.0 --port 8000 \
  > /tmp/seg_server_fastapi.log 2>&1 < /dev/null &
setsid ~/miniconda3/bin/conda run -n seg_server celery -A celery_app:celery_app worker --loglevel=info --pool=solo --concurrency=1 \
  > /tmp/seg_server_celery.log 2>&1 < /dev/null &

# 启动前端
cd /home/wkmgc/Desktop/Seg_Server
setsid npm run dev > /tmp/seg_server_frontend.log 2>&1 < /dev/null &
```

验收：

```bash
curl http://localhost:8000/health
curl -I http://localhost:3000
ps -ef | grep -E "(uvicorn main:app|celery -A celery_app:celery_app worker|tsx server.ts)" | grep -v grep
```

---

## 11. 生产构建方式

前端构建：

```bash
npm run build
```

生产模式启动前端静态服务：

```bash
NODE_ENV=production npm start
```

后端生产启动示例：

```bash
cd backend
uvicorn main:app --host 0.0.0.0 --port 8000
```

Celery worker 仍需要单独启动：

```bash
cd backend
celery -A celery_app:celery_app worker --loglevel=info --pool=solo --concurrency=1
```

实际生产建议用 systemd、supervisor 或容器编排托管 FastAPI、Celery、前端静态服务、MinIO、Redis、PostgreSQL。

---

## 12. 部署验收 Checklist

基础服务：

```bash
pg_isready
redis-cli ping
curl http://localhost:9000/minio/health/live
curl http://localhost:8000/health
```

后端模型状态：

```bash
curl http://localhost:8000/api/ai/models/status
```

前端质量检查：

```bash
npm run lint
npm run test:run
npm run build
```

后端测试：

```bash
conda activate seg_server
python -m pytest backend/tests
```

手工业务验收：

1. 打开 `http://localhost:3000`。
2. 使用 `admin / 123456` 登录。
3. 创建项目或上传视频。
4. 在项目库点击“生成帧”，选择 FPS。
5. Dashboard 中应看到任务进度；Celery 日志应显示拆帧任务。
6. 进入分割工作区，能看到帧、时间轴和画布。
7. 手工画一个多边形 mask，确认顶栏保存状态按钮显示“保存 1 个改动”，点击保存。
8. 刷新工作区后，已保存标注应回显。
9. AI 智能分割中选择可用 SAM 2.1 模型，放置点或框，执行分割。
10. 导出 JSON 或 PNG Mask ZIP。

---

## 13. 常见问题

### 前端打不开或请求后端失败

检查：

```bash
curl http://localhost:8000/health
cat .env
```

如果通过局域网 IP 访问前端，确保：

- `.env` 中 `VITE_API_BASE_URL` 是浏览器可访问的后端地址。
- `backend/.env` 中 `cors_origins` 包含前端地址。

### Dashboard WebSocket 经常断开

检查：

```bash
redis-cli ping
curl http://localhost:8000/health
```

同时确认前端 `VITE_WS_PROGRESS_URL` 指向真实可访问的：

```text
ws://<host>:8000/ws/progress
```

### 生成帧没有进度

检查 Celery worker 是否启动：

```bash
ps aux | grep celery
tail -f /tmp/celery.log
```

检查 Redis：

```bash
redis-cli ping
```

### MinIO 上传失败

检查：

```bash
curl http://localhost:9000/minio/health/live
tail -f /tmp/minio.log
```

如果磁盘空间不足，MinIO 可能拒绝写入。清理 `~/minio_data`、旧日志、旧模型权重或迁移数据目录。

### SAM 2 模型不可用

检查：

```bash
ls -lh models/
curl http://localhost:8000/api/ai/models/status
```

常见原因：

- checkpoint 文件不存在。
- `backend/.env` 中 `sam_model_path` 指向旧文件名。
- `sam2` Python 包未正确安装。
- PyTorch/CUDA 不匹配。

### 不需要 SAM 3

当前版本不用 SAM 3。不要为了正常部署执行 `backend/setup_sam3_env.sh`，也不要在项目里保存 Hugging Face token。
