Files
obsidian-vault/000 daily/FAMILY DeepSeek Harness (dsh) Home Lab Setup.md

128 lines
5.1 KiB
Markdown

---
created: 2026-08-21 20:08
modified: 2026-08-24 09:39
type: note
tags:
- ai
- family
- homelab
aliases: []
---
# [[# DeepSeek Harness (dsh) Home Lab Setup]]
> **IMPLEMENTATION BRIEF for the dsh agent (updated by family-home-lab parent project).**
> The dsh agent builds these instances. The **parent console** (FastAPI portal at `console.lab.audasmedia.com.au`) is built separately and provides login, session routing and tool launching. Read this whole note before deploying.
## 0. Context — what the parent console provides (do NOT rebuild)
The family-home-lab project (`/home/sam/home_network/custom_tools/family_home_lab/plan.md` on .27) deploys on `.13`:
- A FastAPI + Jinja2 + HTMX console at **`console.lab.audasmedia.com.au`** (port `8500` on .13) with per-user login (**Sam, Jo, Harry, Finn**) — bcrypt password auth, signed HTTP-only session cookies.
- The console links to each user's dsh instance after they log in.
- RabbitMQ + Celery workers, PostgreSQL+pgvector, Garage S3 (see [[FAMILY S3 Storage Integration & Blueprint]]).
**dsh must NOT implement its own cross-user account system** — one user per container instance is correct; the console decides which instance a user sees.
## 1. Network environment (verified live)
| Item | Value |
|---|---|
| Subnet | `192.168.20.0/24`, gateway `.1` |
| dsh host | **`.13` nixos-desktop** (`sam@192.168.20.13`), NixOS, Docker host, 15.5 GB RAM |
| Reverse proxy | **Caddy on `.35`** (`sam@192.168.20.35`) — already proxies `*.home.lab`. Add entries there; do NOT run a second Caddy in compose |
| Local DNS | Pi-hole on `.13` — add local records → `.35` |
| LLM routing | **OmniRoute already running at `.13:20129`** (API) / `:20128` (dashboard). Point dsh providers at `http://192.168.20.13:20129/v1` instead of external APIs |
| Open WebUI | Being retired — dsh replaces it as the chat layer |
### Port allocation (avoid collisions — verified in use on .13)
In-use: 53, 1883, 3001, 3002, 4000, 5000, 5432-5434, 5678, 8079-8082, 8088, 8090-8091, 8787, 9001, 9010-9011, 9090-9091, 10200, 20128-20129, plus new family-home-lab stack starting at **8500**.
**dsh instances:** use `3081` (sam), `3082` (jo), `3083` (harry), `3084` (finn).
## 2. System architecture
Subdomains (not subpaths) to prevent WebSocket failures:
```
[ Caddy on .35 ]
│
┌──────────┬────────┼─────────┬──────────────┐
▼ ▼ ▼ ▼ ▼
dsh-sam dsh-jo dsh-harry dsh-finn console.lab.audasmedia.com.au
:3081 :3082 :3083 :3084 (.13:8500)
```
## 3. Docker Compose (deploy inside `/home/sam/Docker/Containers/dsh/`)
Match existing conventions: PUID/PGID 1000, restart unless-stopped.
```yaml
services:
dsh-sam:
image: node:20-slim
container_name: dsh-sam
command: npx @deepseek-ai/dsh web --port 3080
ports:
- "3081:3080"
volumes:
- /mnt/data/family-home-lab/dsh/sam/workspace:/workspace
- /mnt/data/family-home-lab/dsh/sam/config:/root/.config
restart: unless-stopped
# repeat for jo(:3082), harry(:3084→3083), finn(:3084)
```
Data lives under `/mnt/data/family-home-lab/dsh/<user>/` so it's covered by the Borg backup job.
## 4. Caddy entries (on .35, `/etc/caddy/Caddyfile` or its compose config)
```caddy
dsh-sam.lab.audasmedia.com.au {
reverse_proxy 192.168.20.13:3081
}
dsh-jo.lab.audasmedia.com.au {
reverse_proxy 192.168.20.13:3082
}
dsh-harry.lab.audasmedia.com.au {
reverse_proxy 192.168.20.13:3083
}
dsh-finn.lab.audasmedia.com.au {
reverse_proxy 192.168.20.13:3084
}
```
**Iframe requirement (from parent console):** tools are embedded inline in the console where possible. Ensure Caddy does not add `X-Frame-Options: DENY` and that dsh sets no restrictive CSP frame-ancestors. If dsh sets headers itself, allow framing from `console.lab.audasmedia.com.au`.
**Session handoff (to coordinate with console):** the console links out with a short-lived one-time token (`?token=...`) so users don't re-enter credentials; dsh should accept and exchange it, or at minimum tolerate being launched from the console. Coordinate final design with the parent project.
## 5. Hardening & customizing tools (`dsh.config.yaml`)
Providers point at local OmniRoute:
```yaml
providers:
openai-compatible:
baseUrl: "http://192.168.20.13:20129/v1"
apiKey: "<omniroute-key>"
plugins:
- name: dsh-plugin-file-editor
- name: dsh-plugin-translation
- name: dsh-plugin-ocr
# STRICTLY EXCLUDED for kids' instances:
# - dsh-plugin-shell / persistent-bash
```
Per-user restrictions: Sam full plugins; Jo/Harry/Finn no shell/bash plugins.
## 6. Deployment checklist
1. `mkdir -p /mnt/data/family-home-lab/dsh/{sam,jo,harry,finn}/{workspace,config}`
2. Compose up from `/home/sam/Docker/Containers/dsh/`
3. ~~Pi-hole records~~ not needed — public DNS `*.lab.audasmedia.com.au` already resolves to `.35`
4. Add Caddyfile entries on .35, reload
5. Configure OmniRoute provider keys per instance
6. Verify WebSocket connectivity through Caddy
7. Notify parent project when URLs are live so console tool cards can link them