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

82 lines
3.4 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.
#
# Docker Hub 镜像:默认经毫秒镜像 docker.1ms.runhttps://1ms.run/);与 Dockerfile Python 基础镜像一致。
# 拉取失败时可全局替换为 m.daocloud.io/docker.io/... 或配置 daemon registry-mirrors。
#
# 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: docker.1ms.run/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
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:-}
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: