# 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 不是 GPU,AI 自动推理/传播会失败。此时重建并重启二者: ```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 API:http://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`。