Files
operating-room-monitor-server/docker-compose.prod.yml
2026-04-28 17:19:25 +08:00

104 lines
4.7 KiB
YAML
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.
# Production stack for the current codebase: FastAPI + PostgreSQL.
# The API hard-fails on startup if the database is not reachable, so DB health is required.
#
# API 的 Dockerfile 必须使用带 DaoCloud 前缀的 Python 基础镜像m.daocloud.io/docker.io/library/python:...
# 不能使用「FROM python:...」,否则会直连 registry-1.docker.io 导致构建失败。
#
# Base images: DaoCloud「增加前缀」镜像README 推荐,减少 BuildKit 直连 registry-1.docker.io
# See https://github.com/DaoCloud/public-image-mirror
#
# The ``api`` service is built from ``Dockerfile``: Debian apt → 阿里云, uv/PyPI → 清华,
# PyTorch CPU wheels / pytorch.org index files → 南大镜像; see Dockerfile for details.
#
# Published API port defaults to 38080 on the host (override with API_PORT).
#
# GPU (NVIDIA) inference: uv.lock pins torch/torchvision from the PyTorch *CPU* index (see pyproject.toml).
# For CUDA on Linux, use a separate image/lockfile that installs torch+cu*, NVIDIA Container Toolkit on the host,
# and assign GPUs to the api service (deploy.resources.reservations.devices).
services:
db:
image: m.daocloud.io/docker.io/library/postgres:16-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB:-operation_room}
volumes:
- pgdata_prod:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
api:
build:
context: .
dockerfile: Dockerfile
# 容器内访问「宿主机上监听的 RTSP」假流 / MediaMTX 等)需要解析 host.docker.internal。
# Linux 默认无该主机名host-gateway 解析为宿主机在容器网桥上的地址Docker 20.10+)。
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}
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 backends (RTSP / optional Hikvision SDK) — see docs/video-backends.md
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 拉 RTSPTCP 在容器 NAT/防火墙场景下比 UDP 更可靠;可用 .env 覆盖为空禁用
OPENCV_FFMPEG_CAPTURE_OPTIONS: ${OPENCV_FFMPEG_CAPTURE_OPTIONS:-rtsp_transport;tcp}
# 语音待确认TTS/ASR 需百度resolve 上传 WAV 还需 MinIO见 .env.example
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: ${MINIO_ENDPOINT:-}
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-}
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-}
MINIO_BUCKET: ${MINIO_BUCKET:-operation-room-voice}
MINIO_SECURE: ${MINIO_SECURE:-false}
MINIO_REGION: ${MINIO_REGION:-}
DEMO_CORS_ENABLED: ${DEMO_CORS_ENABLED:-false}
DEMO_CORS_ORIGINS: ${DEMO_CORS_ORIGINS:-*}
ports:
- "${API_PORT:-38080}:8000"
depends_on:
db:
condition: service_healthy
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: 10s
volumes:
pgdata_prod: