Files
ruvnet--RuView/docker/Dockerfile.rust
T
ruv 2154b6931c fix(docker): include HA-DISCO MQTT + cog-ha-matter; restores #794
Three changes:
1. Dockerfile.rust now builds sensing-server with `--features mqtt`
   (ADR-115 HA-DISCO publisher) and also builds + ships the
   cog-ha-matter binary (ADR-116 Home Assistant + Matter cog with
   mDNS, embedded broker, RuVector-backed thresholds, Ed25519 witness).
   Adds EXPOSE 1883 for the embedded MQTT broker.

2. docker-entrypoint.sh routes `docker run <image> cog-ha-matter ...`
   (or `ha-matter`) to /app/cog-ha-matter, defaulting --sensing-url to
   http://127.0.0.1:3000 so a docker-compose deployment works out of
   the box. The default entrypoint (no first arg) still launches
   sensing-server unchanged.

3. Workflow path filter now also fires on changes to
   v2/crates/wifi-densepose-bfld/** and v2/crates/cog-ha-matter/**
   so future iteration on those crates rebuilds the image.

DOCKERHUB_TOKEN rotated separately (was expired since 2026-05-13,
which is why the last 5 workflow runs failed at the Docker Hub login
step and `latest` on Docker Hub has stayed amd64-only despite #631
being merged). With this commit + rotated token, the next CI run
should land a multi-arch `:latest` with HA-DISCO + cog-ha-matter +
BFLD support.

Reproduced kutayozdur's pull failure on ruv-mac-mini (Apple Silicon,
Darwin arm64) via Tailscale before fixing.

Refs #794, #631, ADR-115, ADR-116, ADR-118.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-25 15:29:43 -04:00

93 lines
3.6 KiB
Docker

# WiFi-DensePose Rust Sensing Server
# Includes RuVector signal intelligence crates
# Multi-stage build for minimal final image
# Stage 1: Build
FROM rust:1.85-bookworm AS builder
WORKDIR /build
# Copy workspace files
COPY v2/Cargo.toml v2/Cargo.lock ./
COPY v2/crates/ ./crates/
# Copy vendored RuVector crates
COPY vendor/ruvector/ /build/vendor/ruvector/
# Build release binaries:
# - sensing-server with `mqtt` feature so the HA-DISCO MQTT publisher
# (ADR-115) is wired in (auto-discovery topics flow to Home Assistant)
# - cog-ha-matter, the ADR-116 Cognitum cog that wraps HA-DISCO +
# HA-MIND + mDNS + embedded broker for Home Assistant / Matter
RUN cargo build --release -p wifi-densepose-sensing-server --features mqtt 2>&1 \
&& cargo build --release -p cog-ha-matter 2>&1 \
&& strip target/release/sensing-server target/release/cog-ha-matter
# Stage 2: Runtime
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy binaries
COPY --from=builder /build/target/release/sensing-server /app/sensing-server
COPY --from=builder /build/target/release/cog-ha-matter /app/cog-ha-matter
# Copy UI assets
COPY ui/ /app/ui/
# Sanity-check the assets the runtime actually serves (regression guard for
# #520/#514 — the published image must include the observatory and pose-fusion
# dashboards, not just the legacy `index.html` set). Build fails if any of
# these are missing, so a stale image can't be silently pushed.
RUN set -e; \
for f in /app/ui/index.html /app/ui/observatory.html /app/ui/pose-fusion.html /app/ui/viz.html; do \
test -f "$f" || { echo "FATAL: missing UI asset $f"; exit 1; }; \
done; \
for d in /app/ui/observatory /app/ui/pose-fusion /app/ui/components /app/ui/services; do \
test -d "$d" || { echo "FATAL: missing UI directory $d"; exit 1; }; \
done; \
test -x /app/sensing-server || { echo "FATAL: /app/sensing-server is not executable"; exit 1; }; \
test -x /app/cog-ha-matter || { echo "FATAL: /app/cog-ha-matter is not executable"; exit 1; }; \
echo "image assets OK"
# Optional bearer-token auth on /api/v1/*: leave unset for LAN-mode (default),
# set to enforce `Authorization: Bearer <token>` (see bearer_auth module, #443).
# docker run -e RUVIEW_API_TOKEN=$(openssl rand -hex 32) ...
ENV RUVIEW_API_TOKEN=
# HTTP API
EXPOSE 3000
# WebSocket
EXPOSE 3001
# ESP32 UDP
EXPOSE 5005/udp
# MQTT broker (cog-ha-matter embedded broker — Home Assistant + Matter)
EXPOSE 1883
ENV RUST_LOG=info
# CSI_SOURCE controls which data source the sensing server uses at startup.
# auto — probe UDP port 5005 for an ESP32 first; fall back to simulation (default)
# esp32 — receive real CSI frames from an ESP32 device over UDP port 5005
# wifi — use host Wi-Fi RSSI/scan data (Windows netsh; not available in containers)
# simulated — generate synthetic CSI frames (no hardware required)
# Override at runtime: docker run -e CSI_SOURCE=esp32 ...
ENV CSI_SOURCE=auto
# MODELS_DIR controls where the server scans for .rvf model files.
# Mount a host directory here to make models visible to the API:
# docker run -v /path/to/models:/app/models -e MODELS_DIR=/app/models ...
ENV MODELS_DIR=data/models
COPY docker/docker-entrypoint.sh /app/docker-entrypoint.sh
# Exec-form ENTRYPOINT so Docker appends user arguments correctly.
# Pass flags directly: docker run <image> --source esp32 --tick-ms 500
# Or use env vars: docker run -e CSI_SOURCE=esp32 <image>
ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD []