services: # Producer: the ONLY service that touches hardware (smartctl/sg_ses/zpool/ # ledctl). Serialized + paced; writes everything to Redis. poller: build: . image: docker.adamksmith.xyz/jbod-monitor:latest container_name: jbod-poller restart: unless-stopped privileged: true pid: host network_mode: host command: ["python", "-u", "poller.py"] volumes: - /dev:/dev - /sys:/sys:ro - /run/udev:/run/udev:ro environment: - TZ=America/Denver - ZFS_USE_NSENTER=true - REDIS_HOST=127.0.0.1 - REDIS_PORT=6379 - REDIS_DB=0 # Pacing — keep the SAS bus quiet. POLL_CONCURRENCY=1 fully serializes. - POLL_SWEEP_INTERVAL=300 - POLL_DRIVE_GAP=0.5 - POLL_CONCURRENCY=1 - POLL_STARTUP_JITTER=10 - POLL_DATA_TTL=900 depends_on: - redis # Consumer: REST API + web UI + Home Assistant MQTT. Reads Redis only — # unprivileged, no /dev, can restart freely without touching hardware. app: build: . image: docker.adamksmith.xyz/jbod-monitor:latest container_name: jbod-monitor restart: unless-stopped network_mode: host environment: - TZ=America/Denver - UVICORN_LOG_LEVEL=info - REDIS_HOST=127.0.0.1 - REDIS_PORT=6379 - REDIS_DB=0 # Home Assistant MQTT publishing (EMQX, bridged to Mosquitto HA add-on). - MQTT_HOST=10.5.30.3 - MQTT_PORT=1883 - MQTT_DISCOVERY_PREFIX=homeassistant - MQTT_BASE_TOPIC=jbod-monitor - MQTT_PUBLISH_INTERVAL=60 # Broker credentials (MQTT_USERNAME/MQTT_PASSWORD). Optional: container # starts without it (MQTT just won't authenticate). env_file: - path: /etc/jbod-monitor/mqtt.env required: false depends_on: - redis redis: image: redis:7-alpine container_name: jbod-redis restart: unless-stopped network_mode: host volumes: - redis-data:/data command: redis-server --save 60 1 --loglevel warning volumes: redis-data: