Standardize NOMAD host-run service paths
This commit is contained in:
@@ -19,6 +19,16 @@ Each stack contains:
|
|||||||
- `.env.example` — committed with placeholder values
|
- `.env.example` — committed with placeholder values
|
||||||
- optional init scripts (e.g. `initdb/`, `initdb-mariadb/`)
|
- optional init scripts (e.g. `initdb/`, `initdb-mariadb/`)
|
||||||
|
|
||||||
|
## Host-Run Services
|
||||||
|
If something on NOMAD is not deployed as a Docker compose stack, its live runtime belongs under `/opt/<service>`.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- `/opt/project-nomad`
|
||||||
|
- `/opt/newt`
|
||||||
|
- `/opt/doris-dashboard`
|
||||||
|
|
||||||
|
Use the repo for source/staging, but do not run production host services from an agent workspace or random checkout under `/home/fizzlepoof/.openclaw/workspace`.
|
||||||
|
|
||||||
## Deployment Order
|
## Deployment Order
|
||||||
1. `databases/` — must be up before anything else
|
1. `databases/` — must be up before anything else
|
||||||
2. `infrastructure/` — newt creates the pangolin network
|
2. `infrastructure/` — newt creates the pangolin network
|
||||||
|
|||||||
@@ -185,10 +185,11 @@ These are expected to be managed by Wings/Pelican rather than a local compose fi
|
|||||||
- Project N.O.M.A.D.-managed app containers stay exactly as-is and are **hands-off** unless John explicitly says otherwise.
|
- Project N.O.M.A.D.-managed app containers stay exactly as-is and are **hands-off** unless John explicitly says otherwise.
|
||||||
- `whisper` and `node-exporter` are not protected services; they can be removed, but their exact runtime has been documented above for rebuild/recovery.
|
- `whisper` and `node-exporter` are not protected services; they can be removed, but their exact runtime has been documented above for rebuild/recovery.
|
||||||
- Pelican/Wings-managed game containers are part of the permanent game-server stack on NOMAD and stay in place.
|
- Pelican/Wings-managed game containers are part of the permanent game-server stack on NOMAD and stay in place.
|
||||||
- Doris Dashboard source now lives in the canonical homelab repo at `/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard` rather than the old workspace-only repo.
|
- Doris Dashboard source belongs in the homelab repo, and the live NOMAD runtime belongs at `/opt/doris-dashboard`.
|
||||||
|
|
||||||
### Doris Dashboard (local NOMAD homepage)
|
### Doris Dashboard (local NOMAD homepage)
|
||||||
- Canonical repo path: `/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard`
|
- Live runtime path: `/opt/doris-dashboard`
|
||||||
|
- Repo source path: `/home/fizzlepoof/repos/truenas-stacks/home/doris-dashboard`
|
||||||
- Purpose: local-only dashboard for briefing/news/weather/homelab pulse/Paperless review on NOMAD
|
- Purpose: local-only dashboard for briefing/news/weather/homelab pulse/Paperless review on NOMAD
|
||||||
- Generator: `home/doris-dashboard/bin/generate_dashboard.py`
|
- Generator: `home/doris-dashboard/bin/generate_dashboard.py`
|
||||||
- Interactive LAN server: `home/doris-dashboard/bin/dashboard_server.py`
|
- Interactive LAN server: `home/doris-dashboard/bin/dashboard_server.py`
|
||||||
@@ -196,7 +197,12 @@ These are expected to be managed by Wings/Pelican rather than a local compose fi
|
|||||||
- Runtime notes:
|
- Runtime notes:
|
||||||
- Generated output and queue snapshots are runtime data; source/config lives in git, generated JSON/HTML does not need to be treated as canonical.
|
- Generated output and queue snapshots are runtime data; source/config lives in git, generated JSON/HTML does not need to be treated as canonical.
|
||||||
- Topic thumbs write back to `doris-digest/data/feedback.json`.
|
- Topic thumbs write back to `doris-digest/data/feedback.json`.
|
||||||
- Paperless acknowledge/dismiss state writes to `home/doris-dashboard/data/paperless_review_state.json` on the local checkout.
|
- Paperless acknowledge/dismiss state writes to `/opt/doris-dashboard/data/paperless_review_state.json` on the live host.
|
||||||
|
|
||||||
|
### Host-run service path rule
|
||||||
|
- Docker/compose-managed stacks live under `/mnt/docker-ssd/docker/compose`.
|
||||||
|
- Host-run services that are not compose stacks live under `/opt/<service>`.
|
||||||
|
- Do not run production services from any agent workspace or ad-hoc checkout under `/home/fizzlepoof/.openclaw/workspace`.
|
||||||
|
|
||||||
### Safe to remove / how to restore
|
### Safe to remove / how to restore
|
||||||
#### Safe to remove now
|
#### Safe to remove now
|
||||||
|
|||||||
@@ -2,16 +2,22 @@
|
|||||||
|
|
||||||
Local static homepage for John’s morning briefing and peek-anytime news dashboard.
|
Local static homepage for John’s morning briefing and peek-anytime news dashboard.
|
||||||
|
|
||||||
Canonical path:
|
Live runtime path:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
|
/opt/doris-dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
Source path in the homelab repo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/home/fizzlepoof/repos/truenas-stacks/home/doris-dashboard
|
||||||
```
|
```
|
||||||
|
|
||||||
Generated page:
|
Generated page:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/public/index.html
|
/opt/doris-dashboard/public/index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
## What it shows
|
## What it shows
|
||||||
@@ -29,14 +35,14 @@ Generated page:
|
|||||||
## Generate manually
|
## Generate manually
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
|
cd /opt/doris-dashboard
|
||||||
bin/generate_dashboard.py
|
bin/generate_dashboard.py
|
||||||
```
|
```
|
||||||
|
|
||||||
## Preview locally
|
## Preview locally
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/public
|
cd /opt/doris-dashboard/public
|
||||||
python3 -m http.server 8787
|
python3 -m http.server 8787
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -54,9 +60,10 @@ Installed in `fizzlepoof`’s crontab:
|
|||||||
|
|
||||||
```cron
|
```cron
|
||||||
# BEGIN DORIS DASHBOARD
|
# BEGIN DORIS DASHBOARD
|
||||||
DORIS_DASHBOARD_DIR=/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
|
DORIS_DASHBOARD_DIR=/opt/doris-dashboard
|
||||||
# Refresh local dashboard after digest collection windows.
|
DORIS_DIGEST_DIR=/home/fizzlepoof/.openclaw/workspace/doris-digest
|
||||||
5,35 6-23 * * * cd $DORIS_DASHBOARD_DIR && bin/generate_dashboard.py >> logs/generate.log 2>&1
|
# Refresh local dashboard after digest collection windows; wrapper enforces Chicago daytime.
|
||||||
|
5,35 * * * * cd $DORIS_DASHBOARD_DIR && bin/cron_generate_dashboard.sh >> logs/generate.log 2>&1
|
||||||
# END DORIS DASHBOARD
|
# END DORIS DASHBOARD
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -139,7 +146,7 @@ Added sections/data:
|
|||||||
The generated page still lives at:
|
The generated page still lives at:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/public/index.html
|
/opt/doris-dashboard/public/index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
And the LAN service remains:
|
And the LAN service remains:
|
||||||
@@ -151,7 +158,7 @@ http://10.5.1.16:8787/
|
|||||||
Verification commands:
|
Verification commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
|
cd /opt/doris-dashboard
|
||||||
python3 -m py_compile bin/generate_dashboard.py
|
python3 -m py_compile bin/generate_dashboard.py
|
||||||
bin/generate_dashboard.py
|
bin/generate_dashboard.py
|
||||||
curl -fsS http://127.0.0.1:8787/ | grep 'Doris Dashboard'
|
curl -fsS http://127.0.0.1:8787/ | grep 'Doris Dashboard'
|
||||||
@@ -190,7 +197,7 @@ Implementation notes:
|
|||||||
Verify:
|
Verify:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
|
cd /opt/doris-dashboard
|
||||||
bin/generate_dashboard.py
|
bin/generate_dashboard.py
|
||||||
python3 - <<'PY'
|
python3 - <<'PY'
|
||||||
import json
|
import json
|
||||||
@@ -219,6 +226,16 @@ Important note:
|
|||||||
|
|
||||||
- The interactive actions require the dashboard to be served by `bin/dashboard_server.py`, not plain `python -m http.server`.
|
- The interactive actions require the dashboard to be served by `bin/dashboard_server.py`, not plain `python -m http.server`.
|
||||||
|
|
||||||
|
## Runtime path sanity
|
||||||
|
|
||||||
|
The live systemd unit and crontab must point only at:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/opt/doris-dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not run the dashboard from an agent workspace. Agent workspaces are for editing and staging; NOMAD host-run services belong under `/opt/<service>`.
|
||||||
|
|
||||||
## Cron fix — 2026-05-13
|
## Cron fix — 2026-05-13
|
||||||
|
|
||||||
The dashboard cron now uses `bin/cron_generate_dashboard.sh`, which checks America/Chicago daytime internally. This avoids relying on `CRON_TZ`, which NOMAD's cron did not honor consistently.
|
The dashboard cron now uses `bin/cron_generate_dashboard.sh`, which checks America/Chicago daytime internally. This avoids relying on `CRON_TZ`, which NOMAD's cron did not honor consistently.
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
export DORIS_DASHBOARD_DIR="${DORIS_DASHBOARD_DIR:-$(pwd)}"
|
||||||
|
export DORIS_DIGEST_DIR="${DORIS_DIGEST_DIR:-/home/fizzlepoof/.openclaw/workspace/doris-digest}"
|
||||||
|
|
||||||
hour="$(TZ=America/Chicago date +%H)"
|
hour="$(TZ=America/Chicago date +%H)"
|
||||||
if (( 10#$hour < 6 || 10#$hour > 23 )); then exit 0; fi
|
if (( 10#$hour < 6 || 10#$hour > 23 )); then exit 0; fi
|
||||||
bin/generate_dashboard.py
|
bin/generate_dashboard.py
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ Wants=network-online.target
|
|||||||
Type=simple
|
Type=simple
|
||||||
User=fizzlepoof
|
User=fizzlepoof
|
||||||
Group=fizzlepoof
|
Group=fizzlepoof
|
||||||
WorkingDirectory=/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
|
Environment=DORIS_DASHBOARD_DIR=/opt/doris-dashboard
|
||||||
ExecStartPre=/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/bin/generate_dashboard.py
|
Environment=DORIS_DIGEST_DIR=/home/fizzlepoof/.openclaw/workspace/doris-digest
|
||||||
ExecStart=/usr/bin/python3 /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/bin/dashboard_server.py
|
WorkingDirectory=/opt/doris-dashboard
|
||||||
|
ExecStartPre=/opt/doris-dashboard/bin/generate_dashboard.py
|
||||||
|
ExecStart=/usr/bin/python3 /opt/doris-dashboard/bin/dashboard_server.py
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user