2026-05-21 15:56:53 +08:00
|
|
|
|
# Unified backend stack: FastAPI + PostgreSQL + MinIO (GPU via NVIDIA Container Toolkit).
|
2026-05-21 16:02:25 +08:00
|
|
|
|
# Deploy from this directory: docker compose up -d --build
|
|
|
|
|
|
# Client pages (repo root): ../clients/demo-client/start.sh, ../clients/voice-confirmation/start.sh
|
2026-05-21 15:48:03 +08:00
|
|
|
|
services:
|
|
|
|
|
|
db:
|
|
|
|
|
|
image: m.daocloud.io/docker.io/library/postgres:16-alpine
|
|
|
|
|
|
environment:
|
|
|
|
|
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
|
|
|
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
|
|
|
|
|
POSTGRES_DB: ${POSTGRES_DB:-operation_room}
|
2026-05-21 15:56:53 +08:00
|
|
|
|
# Optional: publish PostgreSQL to host for DBA/debug tools (API connects via db:5432 inside compose).
|
2026-05-21 15:48:03 +08:00
|
|
|
|
ports:
|
2026-05-22 10:03:10 +08:00
|
|
|
|
- "${DOCKER_POSTGRES_PUBLISH_PORT:-${POSTGRES_PORT:-45432}}:5432"
|
2026-05-21 15:48:03 +08:00
|
|
|
|
volumes:
|
|
|
|
|
|
- pgdata:/var/lib/postgresql/data
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD-SHELL", "pg_isready -U \"$${POSTGRES_USER}\" -d \"$${POSTGRES_DB}\""]
|
|
|
|
|
|
interval: 5s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 20
|
|
|
|
|
|
start_period: 5s
|
|
|
|
|
|
|
2026-05-22 16:04:32 +08:00
|
|
|
|
mediamtx-hls:
|
|
|
|
|
|
image: ${MEDIAMTX_DOCKER_IMAGE:-m.daocloud.io/docker.io/bluenviron/mediamtx:latest}
|
|
|
|
|
|
container_name: orm-mediamtx-hls
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
entrypoint: ["/bin/sh", "-c"]
|
|
|
|
|
|
command:
|
|
|
|
|
|
- |
|
|
|
|
|
|
if [ ! -f /config/mediamtx.yml ]; then
|
|
|
|
|
|
cp /bootstrap/mediamtx.yml /config/mediamtx.yml
|
|
|
|
|
|
fi
|
|
|
|
|
|
exec /mediamtx /config/mediamtx.yml
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "127.0.0.1:${DEMO_HLS_PREVIEW_PORT:-18888}:8888"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- hls_preview_config:/config
|
|
|
|
|
|
- ./resources/mediamtx_hls_preview.bootstrap.yml:/bootstrap/mediamtx.yml:ro
|
|
|
|
|
|
|
2026-05-21 15:48:03 +08:00
|
|
|
|
minio:
|
|
|
|
|
|
image: m.daocloud.io/docker.io/minio/minio:latest
|
|
|
|
|
|
command: server /data --console-address ":9001"
|
|
|
|
|
|
environment:
|
|
|
|
|
|
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:-minioadmin}
|
|
|
|
|
|
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:-minioadmin}
|
|
|
|
|
|
ports:
|
2026-05-22 09:35:41 +08:00
|
|
|
|
- "${MINIO_PORT:-19000}:9000"
|
|
|
|
|
|
- "${MINIO_CONSOLE_PORT:-19001}:9001"
|
2026-05-21 15:48:03 +08:00
|
|
|
|
volumes:
|
|
|
|
|
|
- minio_data:/data
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
|
|
|
|
|
|
interval: 10s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 5
|
|
|
|
|
|
start_period: 10s
|
|
|
|
|
|
|
|
|
|
|
|
api:
|
|
|
|
|
|
build:
|
|
|
|
|
|
context: .
|
|
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
|
|
network: host
|
2026-05-21 15:56:53 +08:00
|
|
|
|
gpus: all
|
2026-05-21 15:48:03 +08:00
|
|
|
|
extra_hosts:
|
|
|
|
|
|
- "host.docker.internal:host-gateway"
|
|
|
|
|
|
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}
|
|
|
|
|
|
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:-}
|
|
|
|
|
|
OR_SITE_CONFIG_JSON_FILE: ${OR_SITE_CONFIG_JSON_FILE:-}
|
|
|
|
|
|
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:-}
|
|
|
|
|
|
OPENCV_FFMPEG_CAPTURE_OPTIONS: ${OPENCV_FFMPEG_CAPTURE_OPTIONS:-rtsp_transport;tcp}
|
|
|
|
|
|
BAIDU_APP_ID: ${BAIDU_APP_ID:-}
|
|
|
|
|
|
BAIDU_API_KEY: ${BAIDU_API_KEY:-}
|
|
|
|
|
|
BAIDU_SECRET_KEY: ${BAIDU_SECRET_KEY:-}
|
|
|
|
|
|
BAIDU_ASR_DEV_PID: ${BAIDU_ASR_DEV_PID:-1537}
|
|
|
|
|
|
MINIO_ENDPOINT: ${DOCKER_MINIO_ENDPOINT:-minio:9000}
|
|
|
|
|
|
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
|
|
|
|
|
|
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
|
|
|
|
|
|
MINIO_BUCKET: ${MINIO_BUCKET:-operation-room-voice}
|
|
|
|
|
|
MINIO_SECURE: ${MINIO_SECURE:-false}
|
|
|
|
|
|
MINIO_REGION: ${MINIO_REGION:-}
|
|
|
|
|
|
DEMO_CORS_ENABLED: ${DEMO_CORS_ENABLED:-true}
|
|
|
|
|
|
DEMO_CORS_ORIGINS: ${DEMO_CORS_ORIGINS:-*}
|
|
|
|
|
|
DEMO_ORCHESTRATOR_ENABLED: ${DEMO_ORCHESTRATOR_ENABLED:-false}
|
|
|
|
|
|
DEMO_ORCHESTRATOR_RTSP_PORT: ${DEMO_ORCHESTRATOR_RTSP_PORT:-18554}
|
|
|
|
|
|
DEMO_ORCHESTRATOR_RTSP_JSON_HOST: ${DOCKER_DEMO_ORCHESTRATOR_RTSP_JSON_HOST:-host.docker.internal}
|
2026-05-22 16:04:32 +08:00
|
|
|
|
# api 使用 network:host,经宿主机端口访问 mediamtx-hls(勿用 mediamtx-hls 主机名)
|
|
|
|
|
|
DEMO_HLS_PREVIEW_UPSTREAM: ${DEMO_HLS_PREVIEW_UPSTREAM:-http://127.0.0.1:18888}
|
|
|
|
|
|
DEMO_HLS_PREVIEW_CONFIG_DIR: ${DEMO_HLS_PREVIEW_CONFIG_DIR:-/hls-preview-config}
|
|
|
|
|
|
DEMO_HLS_PREVIEW_CONTAINER_NAME: ${DEMO_HLS_PREVIEW_CONTAINER_NAME:-orm-mediamtx-hls}
|
2026-05-21 15:48:03 +08:00
|
|
|
|
MEDIAMTX_DOCKER_IMAGE: ${MEDIAMTX_DOCKER_IMAGE:-m.daocloud.io/docker.io/bluenviron/mediamtx:latest}
|
|
|
|
|
|
command: >
|
|
|
|
|
|
sh -c "uv run --no-sync alembic upgrade head &&
|
|
|
|
|
|
uv run --no-sync uvicorn main:app --host 0.0.0.0 --port 8000"
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "${API_PORT:-38080}:8000"
|
2026-05-22 16:04:32 +08:00
|
|
|
|
volumes:
|
|
|
|
|
|
- hls_preview_config:/hls-preview-config
|
|
|
|
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
2026-05-21 15:48:03 +08:00
|
|
|
|
depends_on:
|
|
|
|
|
|
db:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
minio:
|
|
|
|
|
|
condition: service_started
|
2026-05-22 16:04:32 +08:00
|
|
|
|
mediamtx-hls:
|
|
|
|
|
|
condition: service_started
|
2026-05-21 15:48:03 +08:00
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
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: 20s
|
|
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
pgdata:
|
|
|
|
|
|
minio_data:
|
2026-05-22 16:04:32 +08:00
|
|
|
|
hls_preview_config:
|