Ship Node production images, Unraid compose, and Gitea CI/CD (test then push registry images; cron script if no runner). Rebuild dealer flow as a heatmap-first map with integrity gates and chart helpers. Add confluence zone rules, session clock, capture evidence, and tighter 13F/queue/options paths, plus the matching UI and tests.
119 lines
5.2 KiB
Markdown
119 lines
5.2 KiB
Markdown
# Deploy Investor Flow on Unraid
|
|
|
|
Two containers: **backend** (`:3001`, SQLite + queue) and **frontend** (`:3000`, Next.js, proxies `/api` to the backend). Git and Actions already live on this Unraid box at `http://unraid.local:3003/transnet/investor-flow`.
|
|
|
|
The current Gitea repo has Actions enabled but **no runner registered**, so every CI run is cancelled. Follow "One-time: Gitea runner" below if you want push-to-main to test and publish images.
|
|
|
|
## What you get
|
|
|
|
| Path | Role |
|
|
|---|---|
|
|
| `docker-compose.yml` | Build-from-git stack (works on Unraid or a laptop) |
|
|
| `deploy/unraid/compose.pull.yml` | Pull prebuilt images from the Gitea registry |
|
|
| `deploy/unraid/.env.example` | Secrets + ports + data dir |
|
|
| `deploy/unraid/act-runner-compose.yml` | Gitea act_runner so CI/CD actually runs |
|
|
| `deploy/unraid/user-scripts/sync-and-up.sh` | Cron CD: `git pull` + `compose up --build` |
|
|
| `.github/workflows/ci.yml` | Tests on every push / PR |
|
|
| `.github/workflows/cd.yml` | Build + push images on `main` |
|
|
|
|
## Unraid layout (recommended)
|
|
|
|
Use a **cache (or single-disk) path** for SQLite. `/mnt/user/...` is FUSE and can corrupt WAL files.
|
|
|
|
```
|
|
/mnt/cache/appdata/investor-flow/
|
|
repo/ git checkout (this repo)
|
|
data/ investor-flow.db + harvest files
|
|
.env secrets (not in git)
|
|
```
|
|
|
|
## First-time stack
|
|
|
|
SSH to Unraid (or Unraid terminal):
|
|
|
|
```bash
|
|
mkdir -p /mnt/cache/appdata/investor-flow/data
|
|
git clone http://unraid.local:3003/transnet/investor-flow.git \
|
|
/mnt/cache/appdata/investor-flow/repo
|
|
|
|
cp /mnt/cache/appdata/investor-flow/repo/deploy/unraid/.env.example \
|
|
/mnt/cache/appdata/investor-flow/.env
|
|
nano /mnt/cache/appdata/investor-flow/.env
|
|
```
|
|
|
|
Required in `.env`:
|
|
|
|
- `IFLOW_SESSION_SECRET` — `openssl rand -hex 32`
|
|
- `SEC_OPERATOR_EMAIL` — real address (SEC + Yahoo user-agent)
|
|
- `LLM_PROVIDER_URL` — Ornith LAN URL, e.g. `http://10.37.0.165:30081/v1` (not `localhost`)
|
|
- `IFLOW_DATA_DIR=/mnt/cache/appdata/investor-flow/data`
|
|
|
|
If you copy today's Mac DB into `data/`, also set `IFLOW_CRYPTO_KEY` to the same value the Mac used. If the Mac never set one, encrypted X/FRED rows used the built-in dev key; re-enter those keys in Admin after a fresh Unraid DB instead of guessing.
|
|
|
|
Optional: copy the existing database (stop the Mac backend first so WAL is clean):
|
|
|
|
```bash
|
|
# from the Mac, after stopping :3001
|
|
scp app/server/data/investor-flow.db* \
|
|
root@unraid.local:/mnt/cache/appdata/investor-flow/data/
|
|
```
|
|
|
|
Build and start:
|
|
|
|
```bash
|
|
cd /mnt/cache/appdata/investor-flow/repo
|
|
docker compose --env-file /mnt/cache/appdata/investor-flow/.env up -d --build
|
|
```
|
|
|
|
Open `http://unraid.local:3000`. Backend health: `http://unraid.local:3001/health`.
|
|
|
|
Compose Manager plugin: create a stack whose project directory is the repo checkout and whose env file is `/mnt/cache/appdata/investor-flow/.env`.
|
|
|
|
Reverse proxy (SWAG / NPM): point the host at **frontend :3000 only**. The browser talks same-origin `/api`; the Next container reaches the backend on the compose network.
|
|
|
|
## One-time: Gitea runner (unlocks CI + image CD)
|
|
|
|
1. Gitea → Site Administration → Actions → Runners → **Create new runner**. Copy the token.
|
|
2. Unraid Docker: add insecure registry `10.37.0.86:3003` (Gitea HTTP) so pulls/pushes work. Restart Docker.
|
|
3. Start the runner:
|
|
|
|
```bash
|
|
cd /mnt/cache/appdata/investor-flow/repo
|
|
export GITEA_RUNNER_REGISTRATION_TOKEN=... # from step 1
|
|
export GITEA_INSTANCE_URL=http://10.37.0.86:3003
|
|
docker compose -f deploy/unraid/act-runner-compose.yml up -d
|
|
```
|
|
|
|
4. Confirm the runner is **Idle** on the Gitea runners page.
|
|
5. Repo → Settings → Actions → Secrets: `REGISTRY_TOKEN` = a Gitea token with `write:package` and `write:repository`.
|
|
6. Push to `main`. CI should run tests; CD should push:
|
|
|
|
- `10.37.0.86:3003/transnet/investor-flow-backend:latest`
|
|
- `10.37.0.86:3003/transnet/investor-flow-frontend:latest`
|
|
|
|
Then switch `.env` image names to those registry tags and use `deploy/unraid/compose.pull.yml` so Unraid no longer builds on the array.
|
|
|
|
## CD that works before a runner exists
|
|
|
|
Unraid → User Scripts → new script, paste `deploy/unraid/user-scripts/sync-and-up.sh`, schedule every 10 minutes (or after you push). It fast-forwards `main` and rebuilds only when HEAD moved.
|
|
|
|
A push to Gitea is then: write code → `git push origin main` → cron on Unraid rebuilds containers.
|
|
|
|
## Day-2 operations
|
|
|
|
| Task | How |
|
|
|---|---|
|
|
| Logs | `docker compose logs -f --tail=200 backend frontend` |
|
|
| Restart | `docker compose up -d` |
|
|
| Update (pull mode) | `docker compose -f deploy/unraid/compose.pull.yml pull && docker compose -f deploy/unraid/compose.pull.yml up -d` |
|
|
| Backup DB | copy `/mnt/cache/appdata/investor-flow/data/investor-flow.db*` (stop backend first, or use SQLite backup) |
|
|
| Ornith | keep `LLM_PROVIDER_URL` on the LAN IP; user LLM endpoint in Settings can stay `http://10.37.0.165:30081/v1` |
|
|
|
|
The backend process must stay up for dealer-map snapshots and the queue. `restart: unless-stopped` plus Unraid array autostart covers that.
|
|
|
|
## What this is not
|
|
|
|
- Not Vercel. Next standalone + the Node backend both run on Unraid.
|
|
- `/reports` is still the thin HTML stub. A daily GEX briefing job is separate.
|
|
- Do not publish `IFLOW_SESSION_SECRET`, `IFLOW_CRYPTO_KEY`, or Gitea tokens.
|