# 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.casaos.yml up -d ``` Then open the dashboard: ``` http://:3030/ui/index.html ``` > The bare root `http://:3030/` 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.casaos.yml down ``` --- ## 2. Ports The compose file (`docker-compose.casaos.yml`) publishes **non-default host ports** because 3000/3001 are commonly already in use: | Service | Container | Host (this compose) | Notes | |------------------------|-----------|---------------------|-------| | REST API + web UI | 3000/tcp | **3030** | Dashboard lives here (`/`, `/ui/...`) | | WebSocket sensing feed | 3001/tcp | **3031** | `ws://host:3031/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.casaos.yml`. 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 ` on `/api/v1/*`: ```bash RUVIEW_API_TOKEN=$(openssl rand -hex 32) docker compose -f docker-compose.casaos.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.casaos.yml`. 3. Install. The tile opens `http://:3030/ui/index.html`. **Option B — CLI (CasaOS still detects the container)** ```bash cd /DATA/AppData/ruview docker compose -f docker-compose.casaos.yml up -d ``` > **Icon:** the manifest points at > `https://cdn.jsdelivr.net/gh/Aiacos/ruview@main/assets/ruview-icon.png`. > jsDelivr serves it from the GitHub repo, so commit & push `assets/ruview-icon.png` > to the `main` branch for the icon to resolve. Until then CasaOS shows a > placeholder; everything else works. To use a fully local icon instead, replace > both `icon:` URLs (in `labels:` and `x-casaos:`) with 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 ``` 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.casaos.yml pull docker compose -f docker-compose.casaos.yml up -d # Status of the running server curl -s http://:3030/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 3030/3031:* edit `published:` in `docker-compose.casaos.yml`.