wifi-densepose/docs/DOCKER-CASAOS.md

175 lines
5.9 KiB
Markdown

# Running RuView with Docker (and CasaOS)
This guide covers running the RuView **sensing server** (the Rust + Axum service
that hosts the REST API, WebSocket stream, and web dashboard) as a Docker
container, and importing it into [CasaOS](https://casaos.io/).
It uses the prebuilt image `ruvnet/wifi-densepose:latest` from Docker Hub, so the
host does **not** need to compile the Rust workspace.
> **Architecture note:** the published `:latest` tag currently ships an **amd64**
> layer only. On an amd64 host (e.g. an x86 mini-PC / NUC / Ryzen box) it runs as
> is. On arm64 (Raspberry Pi, etc.) build locally first:
> `docker compose -f docker/docker-compose.yml build`.
---
## 1. Quick start (no hardware)
```bash
cd ruview
CSI_SOURCE=simulated docker compose -f docker-compose.yml up -d
```
Then open the dashboard:
```
http://<host-ip>:3000/ui/index.html
```
> The bare root `http://<host-ip>:3000/` is only an **API index** (a plain list
> of endpoints) — the visual dashboards live under `/ui/`:
> `index.html` (main), `observatory.html` (live feed), `pose-fusion.html`
> (webcam + CSI), `viz.html` (3D).
`CSI_SOURCE=simulated` feeds the pipeline with synthetic CSI so you can explore
the dashboard, API, and vital-sign/pose visualizations without any hardware.
Stop / remove:
```bash
docker compose -f docker-compose.yml down
```
---
## 2. Ports
The compose file (`docker-compose.yml`) publishes these host ports:
| Service | Container | Host | Notes |
|------------------------|-----------|------|-------|
| REST API + web UI | 3000/tcp | **3000** | Dashboard lives here (`/`, `/ui/...`) |
| WebSocket sensing feed | 3001/tcp | **3001** | `ws://host:3001/ws/sensing` |
| ESP32 CSI ingest | 5005/udp | **5005** | ESP32-S3 nodes stream CSI frames here |
If a host port clashes on your machine, edit the `published:` values in
`docker-compose.yml` (and update `port_map` / `webui_port` in the
`x-casaos` block to match the new UI port). The dashboard's WebSocket URL is
derived from the page host, so keep the API and WS ports reachable from the same
hostname.
Verified endpoints (all return `200` once running):
```
/ /ui/index.html /ui/observatory.html
/api/v1/status /api/v1/sensing/latest /api/v1/models
```
---
## 3. Data source modes (`CSI_SOURCE`)
| Value | Behaviour |
|-------------|-----------|
| `auto` | (default) Probe UDP 5005 for an ESP32 node; fall back to `simulated`. |
| `esp32` | Require real CSI frames from an ESP32-S3 node on UDP 5005. |
| `simulated` | Synthetic CSI — no hardware. Best for first evaluation. |
| `wifi` | Host Wi-Fi RSSI/scan (Windows `netsh`) — **not** available inside a Linux container. |
Set it inline (`CSI_SOURCE=esp32 docker compose ... up -d`) or via a `.env` file
next to the compose, or in the CasaOS environment-variable UI.
### Models
Drop `.rvf` model files into `./data/models/` (mounted to `/app/models`); the API
exposes them under `/api/v1/models`. Pretrained weights:
```bash
pip install huggingface_hub
huggingface-cli download ruvnet/wifi-densepose-pretrained --local-dir data/models/wifi-densepose-pretrained
```
### Optional API auth
Leave `RUVIEW_API_TOKEN` empty for LAN-only use. Set it to require
`Authorization: Bearer <token>` on `/api/v1/*`:
```bash
RUVIEW_API_TOKEN=$(openssl rand -hex 32) docker compose -f docker-compose.yml up -d
```
---
## 4. Importing into CasaOS
The compose file includes an `x-casaos:` metadata block (icon, title, category,
description, port map), so CasaOS shows it as a proper app tile.
**Option A — CasaOS UI (Custom Install)**
1. CasaOS dashboard → **App Store****Custom Install** (the `+` / "Install a
customized app").
2. Switch to the **Import** / YAML view and paste the contents of
`docker-compose.yml`.
3. Install. The tile opens `http://<host-ip>:3000/ui/index.html`.
**Option B — CLI (CasaOS still detects the container)**
```bash
cd ruview
docker compose -f docker-compose.yml up -d
```
> **Icon:** the manifest points at
> `https://cdn.jsdelivr.net/gh/ruvnet/RuView@main/assets/ruview-icon.png`
> (jsDelivr serves `assets/ruview-icon.png` straight from the repo). To use a
> different or fully local icon, replace both `icon:` URLs (in `labels:` and
> `x-casaos:`) with another URL or a file path served by your own host.
---
## 5. Connecting live ESP32-S3 CSI nodes
RuView's full capability set (presence through walls, breathing/heart rate, fall
detection, pose) needs **Channel State Information** from a CSI-capable node.
1. Flash the firmware from `firmware/esp32-csi-node/` to an **ESP32-S3**
(8 MB or 4 MB). See the repo `CLAUDE.md` "ESP32 Firmware Build" section.
2. Provision Wi-Fi + the sink (this server's) IP:
```bash
python firmware/esp32-csi-node/provision.py --port /dev/ttyUSB0 \
--ssid "YourWiFi" --password "secret" --target-ip <host-ip>
```
Point `--target-ip` at the host running this container; frames arrive on
**UDP 5005**.
3. Start with `CSI_SOURCE=esp32` (or `auto`).
> **Supported chips:** ESP32-**S3** (dual-core) and ESP32-**C6**. The original
> ESP32 and ESP32-**C3** are **single-core** and cannot run the CSI DSP pipeline.
---
## 6. Operations
```bash
# Logs
docker logs ruview -f --tail 100
# Restart / update to the latest image
docker compose -f docker-compose.yml pull
docker compose -f docker-compose.yml up -d
# Status of the running server
curl -s http://<host-ip>:3000/api/v1/status
```
**Troubleshooting**
- *Dashboard loads but no data:* check the data source — with `auto` and no ESP32
present it falls back to `simulated`; logs print `Data source: ...`.
- *Multiple ESP32 nodes on Docker Desktop for Windows:* multi-source UDP collapses
to one source IP at the WSL boundary. Use the host relay (see
`docs/TROUBLESHOOTING.md §9`). Native Linux/CasaOS hosts are unaffected.
- *Port clash on 3000/3001:* edit `published:` in `docker-compose.yml`.