Files

178 lines
7.0 KiB
YAML
Raw Permalink Normal View History

# Unified backend stack: FastAPI + PostgreSQL + MinIO (GPU via NVIDIA Container Toolkit).
# 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}
# 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
# bluenviron/mediamtx 为 scratch 镜像,仅含 /mediamtx无 /bin/sh用 alpine init 种子配置。
hls-preview-init:
image: m.daocloud.io/docker.io/library/alpine:3.20
restart: "no"
volumes:
- hls_preview_config:/config
- ./resources/mediamtx_hls_preview.bootstrap.yml:/seed/mediamtx.yml:ro
2026-05-22 16:04:32 +08:00
entrypoint: ["/bin/sh", "-c"]
command:
- |
if [ ! -f /config/mediamtx.yml ]; then
cp /seed/mediamtx.yml /config/mediamtx.yml
2026-05-22 16:04:32 +08:00
fi
mediamtx-hls:
image: ${MEDIAMTX_DOCKER_IMAGE:-m.daocloud.io/docker.io/bluenviron/mediamtx:latest}
container_name: orm-mediamtx-hls
restart: unless-stopped
command: ["/config/mediamtx.yml"]
2026-05-22 16:04:32 +08:00
ports:
- "127.0.0.1:${DEMO_HLS_PREVIEW_PORT:-18888}:8888"
volumes:
- hls_preview_config:/config
depends_on:
hls-preview-init:
condition: service_completed_successfully
2026-05-22 16:04:32 +08:00
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
# Match host uid/gid so bind-mounted ./logs (RTSP slices) is readable on the host (VLC, ffplay).
user: "${HOST_UID:-1000}:${HOST_GID:-1000}"
group_add:
- "${DOCKER_GID:-999}"
gpus: all
2026-05-21 15:48:03 +08:00
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
HOST_UID: ${HOST_UID:-1000}
HOST_GID: ${HOST_GID:-1000}
DOCKER_GID: ${DOCKER_GID:-999}
HOME: /tmp
XDG_CACHE_HOME: /tmp
UV_CACHE_DIR: /tmp/uv-cache
2026-05-27 13:48:27 +08:00
TORCH_HOME: /app/.cache/torch
YOLO_CONFIG_DIR: /app/.cache/ultralytics
# Numeric UID in compose has no passwd entry; PyTorch inductor cache must not call getpass.getuser().
TORCHINDUCTOR_CACHE_DIR: /tmp/torchinductor-cache
2026-05-21 15:48:03 +08:00
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}
RTSP_PRIMARY_CAMERA_ID: ${RTSP_PRIMARY_CAMERA_ID:-or-cam-03}
RTSP_RECORD_ALL_CAMERAS: ${RTSP_RECORD_ALL_CAMERAS:-false}
RTSP_SEGMENT_DURATION_SEC: ${RTSP_SEGMENT_DURATION_SEC:-120}
VIDEO_OPEN_TIMEOUT_SEC: ${VIDEO_OPEN_TIMEOUT_SEC:-90}
APP_LOG_DIR: ${APP_LOG_DIR:-logs/app}
APP_LOG_FILE_ENABLED: ${APP_LOG_FILE_ENABLED:-true}
APP_LOG_ROTATION: ${APP_LOG_ROTATION:-7 days}
APP_LOG_RETENTION: ${APP_LOG_RETENTION:-7 days}
2026-05-22 17:18:27 +08:00
# api 在 Compose 桥接网内反代 mediamtx-hls:8888宿主机调试 HLS 仍用 127.0.0.1:18888
DEMO_HLS_PREVIEW_UPSTREAM: ${DEMO_HLS_PREVIEW_UPSTREAM:-http://mediamtx-hls:8888}
2026-05-22 16:04:32 +08:00
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: >
2026-05-27 13:48:27 +08:00
sh -c "mkdir -p /tmp/uv-cache /tmp/torchinductor-cache &&
uv run --no-sync alembic upgrade head &&
2026-05-21 15:48:03 +08:00
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
- ./logs:/app/logs
2026-05-22 16:04:32 +08:00
- /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: