- 以 ConsumableVisionAlgorithmService 替代 consumable_classifier 与 tear_action; 可选手部检测权重,未配置时全帧分类;时间窗众数与 Excel 白名单配置。 - 语音待确认:ASR 先匹配 pending topk,再匹配本台 candidate_consumables; 记账 item_id 与 vision 一致使用 name_to_code。 - 更新 config、Compose、.env.example、依赖(pandas/openpyxl)与测试。 Made-with: Cursor
80 lines
3.0 KiB
YAML
80 lines
3.0 KiB
YAML
# Local development stack. You can either:
|
|
# 1. run `docker compose -f docker-compose.dev.yml up --build` for API + DB in containers, or
|
|
# 2. run `./start.sh` to start only DB and keep the API on the host with hot reload.
|
|
#
|
|
# Default host ports avoid common 5432/8000 clashes when many services run in parallel:
|
|
# Postgres published: POSTGRES_PORT -> 35432 (container still listens on 5432)
|
|
# API published: API_PORT -> 38080 (uvicorn inside container still listens on 8000)
|
|
services:
|
|
db:
|
|
image: postgres:16-alpine
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
|
POSTGRES_DB: ${POSTGRES_DB:-operation_room}
|
|
ports:
|
|
- "${POSTGRES_PORT:-35432}:5432"
|
|
volumes:
|
|
- pgdata_dev:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U \"$${POSTGRES_USER}\" -d \"$${POSTGRES_DB}\""]
|
|
interval: 3s
|
|
timeout: 5s
|
|
retries: 20
|
|
start_period: 5s
|
|
|
|
api:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
|
POSTGRES_DB: ${POSTGRES_DB:-operation_room}
|
|
POSTGRES_HOST: db
|
|
POSTGRES_PORT: 5432
|
|
CONSUMABLE_CLASSIFIER_IMGSZ: ${CONSUMABLE_CLASSIFIER_IMGSZ:-224}
|
|
CONSUMABLE_CLASSIFIER_DEVICE: ${CONSUMABLE_CLASSIFIER_DEVICE:-}
|
|
CONSUMABLE_CLASSIFIER_TOPK: ${CONSUMABLE_CLASSIFIER_TOPK:-5}
|
|
CONSUMABLE_MIN_CLS_CONFIDENCE: ${CONSUMABLE_MIN_CLS_CONFIDENCE:-0.5}
|
|
CONSUMABLE_VISION_WINDOW_SEC: ${CONSUMABLE_VISION_WINDOW_SEC:-15}
|
|
CONSUMABLE_CATALOG_XLSX_PATH: ${CONSUMABLE_CATALOG_XLSX_PATH:-}
|
|
HAND_DETECTION_WEIGHTS: ${HAND_DETECTION_WEIGHTS:-}
|
|
HAND_DETECTION_IMGSZ: ${HAND_DETECTION_IMGSZ:-640}
|
|
HAND_DETECTION_DEVICE: ${HAND_DETECTION_DEVICE:-}
|
|
VIDEO_DEFAULT_BACKEND: ${VIDEO_DEFAULT_BACKEND:-rtsp}
|
|
VIDEO_RTSP_URL_TEMPLATE: ${VIDEO_RTSP_URL_TEMPLATE:-}
|
|
VIDEO_RTSP_URLS_JSON_FILE: ${VIDEO_RTSP_URLS_JSON_FILE:-}
|
|
VIDEO_RTSP_URLS_JSON: ${VIDEO_RTSP_URLS_JSON:-}
|
|
VIDEO_CAMERA_BACKEND_OVERRIDES_JSON: ${VIDEO_CAMERA_BACKEND_OVERRIDES_JSON:-}
|
|
HIKVISION_SDK_ENABLED: ${HIKVISION_SDK_ENABLED:-false}
|
|
HIKVISION_LIB_DIR: ${HIKVISION_LIB_DIR:-/opt/hikvision/lib}
|
|
HIKVISION_DEVICE_IP: ${HIKVISION_DEVICE_IP:-}
|
|
HIKVISION_USER: ${HIKVISION_USER:-}
|
|
HIKVISION_PASSWORD: ${HIKVISION_PASSWORD:-}
|
|
HIKVISION_PREVIEW_RTSP_TEMPLATE: ${HIKVISION_PREVIEW_RTSP_TEMPLATE:-}
|
|
ports:
|
|
- "${API_PORT:-38080}:8000"
|
|
command: ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
|
volumes:
|
|
- ./app:/app/app
|
|
- ./main.py:/app/main.py
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test:
|
|
[
|
|
"CMD",
|
|
"python",
|
|
"-c",
|
|
"import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=2)",
|
|
]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 10s
|
|
|
|
volumes:
|
|
pgdata_dev:
|