Files
RealSense-D435i-G1/docker-compose.yml
T
henrytherobotandClaude Opus 4.7 08977ac6f6 [port] free /dev/video4 by stopping Unitree video_hub_pc4 from container
Mount mscli + master_service.sock into the container and stop
video_hub_pc4 at startup (and every 10s) so the RealSense pipeline
can open the D435i V4L2 node without EBUSY.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 12:24:16 +02:00

105 lines
3.2 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.
services:
# -- NATS Server ----------------------------
nats:
image: nats:latest
profiles: ["nats"]
ports:
- "4222:4222"
- "8222:8222"
command: >
--auth ${NATS_TOKEN:-realsense-dev-token}
--http_port 8222
restart: unless-stopped
healthcheck:
test: ["CMD", "nats-server", "--help"]
interval: 5s
timeout: 3s
retries: 3
start_period: 5s
# -- Backend --------------------------------
backend:
build:
context: .
dockerfile: Dockerfile
# network: host so that build-time apt/git/pip can reach the
# tinyproxy running on the host at localhost:8888.
network: host
privileged: true
ports:
- "${API_PORT:-8878}:8878"
devices:
- "/dev/bus/usb:/dev/bus/usb"
volumes:
- ./images:/app/images
- ./models:/app/models:ro
# mscli + master_service socket so the container can stop the
# Unitree video_hub_pc4 service (it holds /dev/video4 — the D435i
# V4L2 node — and would otherwise make Open() fail with EBUSY).
- /unitree/sbin/mscli:/unitree/sbin/mscli:ro
- /unitree/var/run/master_service.sock:/unitree/var/run/master_service.sock
entrypoint:
- bash
- -c
- |
/unitree/sbin/mscli stopservice video_hub_pc4 >/dev/null 2>&1 || true
sleep 2
( while sleep 10; do /unitree/sbin/mscli stopservice video_hub_pc4 >/dev/null 2>&1 || true; done ) &
exec /app/entrypoint.sh
env_file: .env
depends_on:
nats:
condition: service_healthy
required: false
restart: unless-stopped
labels:
# autoheal monitora SOLO i container con questa label = true
autoheal: "true"
healthcheck:
# Healthcheck "vero": fallisce se camera_open != true.
# Usa /api/health (pubblico, no API key) che già ritorna camera_open.
# 4 retry × 15s ⇒ ~1 min di stato cattivo prima dell'autoheal restart.
test:
- CMD
- python3
- -c
- |
import urllib.request, json, sys
try:
r = urllib.request.urlopen('http://localhost:8878/api/health', timeout=3)
d = json.loads(r.read())
sys.exit(0 if d.get('data', {}).get('camera_open') else 1)
except Exception:
sys.exit(1)
interval: 15s
timeout: 5s
retries: 4
start_period: 30s
# -- Autoheal -------------------------------
# Monitora i container con label `autoheal=true` e li restarta automaticamente
# quando Docker li marca "unhealthy". Risolve il caso "pyrealsense2 SDK stuck".
autoheal:
image: willfarrell/autoheal:latest
container_name: autoheal-d435
restart: always
environment:
AUTOHEAL_CONTAINER_LABEL: autoheal
AUTOHEAL_INTERVAL: 10
AUTOHEAL_START_PERIOD: 30
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
# -- Frontend React Dev (hot reload) --------
frontend-dev:
image: node:20-alpine
working_dir: /app
volumes:
- ./src/frontend/react:/app
- /app/node_modules
command: sh -c "npm ci && npm run dev -- --host 0.0.0.0"
ports:
- "5173:5173"
profiles: [dev]