Files
Pre_Seg_Server/README.md
2026-05-08 00:32:02 +08:00

569 lines
16 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.
# Seg_Server_Docker 部署说明
`Seg_Server_Docker` 是语义分割系统的自包含 Docker 部署包。目标不是“最小可运行”,而是尽量完整、可搬迁、能适应 CPU/GPU 与局域网访问等常见环境的可运行版本。
部署时只需要保留并移动这一整个文件夹。默认配置只引用本目录内的 `models/``demo/`、前端源码、后端源码和 Docker 配置,不依赖旁边的源码仓库,也不依赖固定宿主机路径。
## 目录内容
```text
Seg_Server_Docker/
├── docker-compose.yml # 基础服务前端、后端、worker、PostgreSQL、Redis、MinIO
├── docker-compose.gpu.yml # GPU 覆盖配置:给 backend/worker 透传 NVIDIA GPU
├── Dockerfile.backend # FastAPI + Celery + PyTorch + SAM2 后端镜像
├── Dockerfile.frontend # React 前端构建 + Nginx 静态服务
├── .env # 当前部署环境变量
├── .env.example # 环境变量模板
├── backend/ # FastAPI 后端代码
├── src/ # React 前端代码
├── public/ # 前端静态资源
├── docker/ # Nginx 配置等 Docker 辅助文件
├── demo/ # 演示数据
│ ├── 演视LC视频序列.mp4
│ └── 演视DICOM序列/
└── models/ # SAM 2.1 权重,容器内挂载为 /app/models
```
## 服务说明
| 服务 | 容器名 | 作用 | 默认端口 |
|---|---|---|---|
| frontend | `seg-frontend` | Web 前端页面 | `3000 -> 80` |
| backend | `seg-backend` | FastAPI API、登录、项目、模板、标注、单帧 AI 分割 | `8000 -> 8000` |
| worker | `seg-worker` | Celery 后台任务、视频拆帧、DICOM 解析、AI 自动推理/传播 | 内部访问 |
| postgres | `seg-postgres` | 元数据数据库 | 内部访问 |
| redis | `seg-redis` | Celery broker/result backend | 内部访问 |
| minio | `seg-minio` | 视频、DICOM、帧图、缩略图等对象存储 | `9000``9001` |
`backend` 构建并发布 `seg-server-backend:latest` 镜像,`worker` 直接复用这个镜像。更新后端依赖、PyTorch、SAM2 或系统包时,只需要重建 `backend` 镜像,再同时重启 `backend``worker`,避免 API 端显示模型可用但 worker 执行传播时缺依赖。
`worker` 配置了 `pull_policy: never`,只使用本地 `seg-server-backend:latest`,不会尝试从远端镜像仓库拉取这个内部镜像。首次部署请使用带 `--build` 的启动命令,让 `backend` 先构建出本地镜像。
## 部署前准备
1. 安装 Docker Engine 和 Docker Compose plugin。
2. 确认当前目录包含演示数据:
```bash
ls demo/演视LC视频序列.mp4
ls demo/演视DICOM序列
```
3. 确认当前目录包含 SAM 2.1 权重:
```bash
ls -lh models/
```
推荐至少包含:
```text
models/sam2_hiera_tiny.pt
models/sam2.1_hiera_small.pt
models/sam2.1_hiera_base_plus.pt
models/sam2.1_hiera_large.pt
```
如果只部署部分权重,系统仍可启动;缺失权重对应的模型变体会显示不可用。
### 下载 SAM 2.1 权重
部署分支不提交 `.pt` 权重文件。首次部署前在本目录执行:
```bash
mkdir -p models
wget -O models/sam2_hiera_tiny.pt https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_tiny.pt
wget -O models/sam2.1_hiera_small.pt https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_small.pt
wget -O models/sam2.1_hiera_base_plus.pt https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_base_plus.pt
wget -O models/sam2.1_hiera_large.pt https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_large.pt
```
也可以只下载 tiny/small 等需要的权重。`sam2_hiera_tiny.pt` 是兼容旧名,系统会把它作为 `sam2.1_hiera_tiny` 的 fallback 使用。
## 环境变量
部署前编辑 `.env`
```ini
PUBLIC_HOST=localhost
VITE_API_BASE_URL=
VITE_WS_PROGRESS_URL=
FRONTEND_PORT=3000
BACKEND_PORT=8000
MINIO_PORT=9000
MINIO_CONSOLE_PORT=9001
POSTGRES_USER=seguser
POSTGRES_PASSWORD=segpass123
POSTGRES_DB=segserver
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_PUBLIC_ENDPOINT=localhost:9000
MINIO_SECURE=false
# MINIO_PUBLIC_SECURE=true
SAM_MODELS_DIR=./models
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
```
局域网访问时,把 `PUBLIC_HOST` 改成部署机器 IP并把对应前端地址加入 `CORS_ORIGINS`。例如前端通过 `http://192.168.3.11:3000` 打开时:
```ini
PUBLIC_HOST=192.168.3.11
VITE_API_BASE_URL=
VITE_WS_PROGRESS_URL=
MINIO_PUBLIC_ENDPOINT=192.168.3.11:9000
MINIO_SECURE=false
CORS_ORIGINS=["http://192.168.3.11:3000","http://localhost:3000","http://127.0.0.1:3000"]
```
保持 `SAM_MODELS_DIR=./models` 可以让部署包自包含、可搬迁。只有在刻意共享外部模型缓存时,才把它改成其他路径。
`.env``.env.example` 中用 `# XXXX` 标出的配置项,是局域网部署或公网域名反代部署时最常需要修改的地方。
生产或长期演示环境请修改:
- `JWT_SECRET_KEY`
- `DEFAULT_ADMIN_PASSWORD`
- `POSTGRES_PASSWORD`
- `MINIO_ACCESS_KEY`
- `MINIO_SECRET_KEY`
## CPU 启动
适用于没有 NVIDIA GPU 或暂时不配置 GPU 透传的环境:
```bash
docker compose up -d --build
```
查看状态:
```bash
docker compose ps
curl http://localhost:8000/health
```
CPU 模式下,如果 PyTorch、SAM2 和 `.pt` 权重存在,模型可以加载,但推理速度明显慢于 GPU。
## GPU 启动
GPU 模式要求宿主机满足:
1. NVIDIA 驱动可用。
2. `nvidia-smi` 能看到 GPU。
3. Docker 已安装并配置 NVIDIA Container Toolkit。
4. `docker run --rm --gpus all ... nvidia-smi` 能在容器内看到 GPU。
先验证宿主机 GPU
```bash
nvidia-smi
```
验证 Docker GPU 透传:
```bash
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
```
如果 Docker GPU 验证失败,需要先安装并配置 NVIDIA Container Toolkit
```bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
```
启动 GPU 版:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d --build
```
验证 backend 和 worker 都能看到 GPU
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml exec -T backend python - <<'PY'
import torch
print(torch.cuda.is_available())
print(torch.cuda.device_count())
print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else "NO CUDA")
PY
docker compose -f docker-compose.yml -f docker-compose.gpu.yml exec -T worker python - <<'PY'
import torch
print(torch.cuda.is_available())
print(torch.cuda.device_count())
print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else "NO CUDA")
PY
```
如果 backend 是 GPU 但 worker 不是 GPUAI 自动推理/传播会失败。此时重建并重启二者:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml build backend
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d backend worker
```
## 公网域名 + frpc/frps + NPM
如果公网服务器绑定了域名,并通过 frpc/frps 把内网部署机器端口映射到公网服务器本机端口,再由 Nginx Proxy Manager 反向代理,推荐使用三个子域名:
```text
seg.example.com -> 前端
seg-api.example.com -> 后端 API + WebSocket
seg-minio.example.com -> MinIO 图片/帧图/缩略图
```
推荐链路:
```text
浏览器
-> 公网服务器 NPM
-> 公网服务器本机 frps 映射端口
-> frpc
-> 内网部署机器的 3000 / 8000 / 9000
```
端口映射建议:
```text
内网部署机器 3000 -> 公网服务器本机 13000 -> NPM: seg.example.com
内网部署机器 8000 -> 公网服务器本机 18000 -> NPM: seg-api.example.com
内网部署机器 9000 -> 公网服务器本机 19000 -> NPM: seg-minio.example.com
```
### 可选:使用部署包内置 frpc
部署包已经包含可选 frpc 容器配置,默认不会启动。需要使用时,先编辑:
```text
docker/frpc/frpc.toml
```
文件中用 `# XXXX` 标出的地方需要按你的 frps 服务端配置修改:
```toml
# XXXX 公网 frps 服务器地址
serverAddr = "XX.XX.XX.XX"
# XXXX 公网 frps 服务端口,必须与 frps 的 bindPort 一致
serverPort = 7000
# XXXX 必须替换为 frps 服务端配置中的 token
auth.token = "XXXXX"
```
默认模板已经配置了三个 TCP 代理:
```text
seg-frontend: 内部 frontend:80 -> 远端 13000
seg-backend: 内部 backend:8000 -> 远端 18000
seg-minio: 内部 minio:9000 -> 远端 19000
```
frpc 容器和系统服务在同一个 Docker Compose 网络里,所以 `localIP` 推荐保持为 `frontend``backend``minio` 这些服务名;如果改成宿主机或其他内网 IP也可以按你的实际网络调整。
启用内置 frpc 的 CPU 版启动命令:
```bash
docker compose --profile frpc up -d --build
```
启用内置 frpc 的 GPU 版启动命令:
```bash
docker compose --profile frpc -f docker-compose.yml -f docker-compose.gpu.yml up -d --build
```
只重启 frpc
```bash
docker compose --profile frpc up -d frpc
```
查看 frpc 日志:
```bash
docker compose --profile frpc logs -f frpc
```
不带 `--profile frpc` 的普通启动命令不会启动 frpc
```bash
docker compose up -d
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d
```
NPM 中配置三个 Proxy Host
```text
seg.example.com
Scheme: http
Forward Hostname / IP: 127.0.0.1
Forward Port: 13000
seg-api.example.com
Scheme: http
Forward Hostname / IP: 127.0.0.1
Forward Port: 18000
Websocket Support: 开启
seg-minio.example.com
Scheme: http
Forward Hostname / IP: 127.0.0.1
Forward Port: 19000
```
建议三个域名都在 NPM 里申请 HTTPS 证书,并开启 HTTPS。公网 HTTPS 场景下,内网 `Seg_Server_Docker/.env` 需要修改 `# XXXX` 标出的几项:
```ini
# XXXX Public-domain access through frpc/frps + NPM
PUBLIC_HOST=seg.example.com
# XXXX Frontend build-time API/WebSocket endpoints
VITE_API_BASE_URL=https://seg-api.example.com
VITE_WS_PROGRESS_URL=wss://seg-api.example.com/ws/progress
# XXXX Browser-facing MinIO endpoint
MINIO_PUBLIC_ENDPOINT=seg-minio.example.com
MINIO_SECURE=false
MINIO_PUBLIC_SECURE=true
# XXXX Browser origins
CORS_ORIGINS=["https://seg.example.com"]
```
修改 `VITE_API_BASE_URL``VITE_WS_PROGRESS_URL` 后必须重建前端,因为它们是前端构建期变量:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml build frontend
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d frontend backend worker
```
如果同时从零启动 GPU 版:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d --build
```
公网域名部署后,浏览器只需要访问:
```text
https://seg.example.com
```
不要只反代前端 `3000`。后端 `8000` 不通会导致登录、项目、任务和 AI 接口失败MinIO `9000` 不通会导致帧图、缩略图、预览图等资源加载失败。
## 访问入口
默认地址:
```text
前端http://localhost:3000
后端http://localhost:8000
MinIO APIhttp://localhost:9000
MinIO 控制台http://localhost:9001
```
局域网访问时,把 `localhost` 换成 `.env` 中的 `PUBLIC_HOST`
默认账号:
```text
用户名admin
密码123456
```
## 演示数据和恢复出厂设置
演示数据固定从部署包本地读取:
```text
demo/演视LC视频序列.mp4
demo/演视DICOM序列/
```
系统启动和“恢复演示出厂设置”都会使用这两个路径。恢复后应出现:
- `演视LC视频序列`
- `演视DICOM序列`
DICOM 序列会按文件名自然顺序读取,避免切片顺序错位。
## 常用运维命令
启动:
```bash
docker compose up -d
```
GPU 启动:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d
```
停止:
```bash
docker compose down
```
查看容器:
```bash
docker compose ps
```
查看日志:
```bash
docker compose logs -f backend
docker compose logs -f worker
docker compose logs -f frontend
```
重建前后端:
```bash
docker compose build backend frontend
docker compose up -d backend worker frontend
```
重建 GPU 版后端和 worker
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml build backend
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d backend worker
```
清空当前部署数据:
```bash
docker compose down -v
docker compose up -d --build
```
注意:`down -v` 会删除数据库和 MinIO 对象存储卷,项目、帧、标注和上传文件都会清空。
## 模型状态验证
登录后前端左下角会显示 CPU/GPU 状态。也可以通过后端接口检查:
```bash
curl http://localhost:8000/health
```
模型状态接口需要登录 token。更简单的容器内检查方式
```bash
docker compose exec -T backend python - <<'PY'
from services.sam_registry import sam_registry
print(sam_registry.runtime_status())
PY
```
GPU 版:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml exec -T backend python - <<'PY'
from services.sam_registry import sam_registry
print(sam_registry.runtime_status())
PY
```
## 常见问题
### 前端能打开,但图片或缩略图打不开
检查 `.env`
- `PUBLIC_HOST` 是否是浏览器可以访问到的主机名或 IP。
- `MINIO_PORT` 是否开放。
- `CORS_ORIGINS` 是否包含当前前端地址。
修改 `.env` 后重启:
```bash
docker compose up -d backend worker frontend
```
### 左下角显示 CPU
先确认是 CPU 部署还是 GPU 部署。GPU 部署必须使用:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d
```
再检查 Docker GPU 透传:
```bash
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
```
如果这条命令失败,问题在宿主机 Docker GPU runtime不在应用代码。
### 单帧 AI 分割可用,但 AI 自动推理无结果
检查 `seg-worker` 是否和 `seg-backend` 使用同一个镜像,并且 worker 是否能看到 PyTorch、SAM2 和 GPU
```bash
docker inspect seg-backend seg-worker --format '{{.Name}} {{.Image}} {{.Config.Image}}'
docker compose -f docker-compose.yml -f docker-compose.gpu.yml exec -T worker python - <<'PY'
import importlib.util, torch
print("torch", bool(importlib.util.find_spec("torch")))
print("sam2", bool(importlib.util.find_spec("sam2")))
print("cuda", torch.cuda.is_available())
PY
```
如果 worker 缺依赖,重建并重启:
```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml build backend
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d backend worker
```
### 恢复演示出厂设置后项目为空
检查 demo 文件是否仍在部署包本地:
```bash
ls demo/演视LC视频序列.mp4
ls demo/演视DICOM序列
```
如果目录被移动或删掉,恢复出厂设置无法重新生成演示项目。
### 模型不可用
检查 `models/`
```bash
ls -lh models/
```
缺失的 `.pt` 权重对应模型会显示不可用。部署包默认从 `./models` 挂载到容器内 `/app/models`