From 4af50ec883869b6409e298e920951c75b047de77 Mon Sep 17 00:00:00 2001 From: "F.R.I.D.A.Y." Date: Sun, 31 May 2026 21:38:45 -0400 Subject: [PATCH] docs(fleet): add PegaProx, iVentoy remastering procedures, update admin cheat sheet - fleet/admin-cheat-sheet.md: Added PegaProx section, updated MK33/MK34/MK39 statuses to Online (PVE), added iVentoy remastering notes, iVentoy Pro upgrade pending marker. - procedures/pega-prox-deploy.md: New procedure for deploying PegaProx on Docker Swarm (host mode, CSRF, API gotchas). - procedures/iventoy-remaster-procedure.md: New procedure for remastering Proxmox ISOs with embedded answer URLs and locked gfxmode. - changelog/2026-05-31-pxe-pegaprox-deployment.md: Changelog entry for todays fleet work. - 04-service-catalog.md: Added PegaProx to Management / Dashboard section. --- 04-service-catalog.md | 1 + changelog/changelog-2026-05-31.md | 88 +++++++++ fleet/admin-cheat-sheet.md | 206 ++++++++++++++++++++ procedures/iventoy-remaster-procedure.md | 238 +++++++++++++++++++++++ procedures/pega-prox-deploy.md | 165 ++++++++++++++++ 5 files changed, 698 insertions(+) create mode 100644 changelog/changelog-2026-05-31.md create mode 100644 fleet/admin-cheat-sheet.md create mode 100644 procedures/iventoy-remaster-procedure.md create mode 100644 procedures/pega-prox-deploy.md diff --git a/04-service-catalog.md b/04-service-catalog.md index cc6acb3..951ee93 100644 --- a/04-service-catalog.md +++ b/04-service-catalog.md @@ -38,6 +38,7 @@ | Service | Image | Pulls | Stars | Updated | Placement | Notes | |---------|-------|-------|-------|---------|-----------|-------| | **Portainer CE** | `portainer/portainer-ce` | 1.46B | 2,665 | 2026-05-20 | **Replicated (1)** | MK7 — agentless mode, no portainer-agent needed | +| **PegaProx** | `pegaprox/pegaprox` | — | — | — | **Manager Constraint** | MK7 — PVE cluster manager (host mode ports 5000-5002) | | **Homepage** | `gethomepage/homepage` | 1.31M | 40 | 2026-05-25 | **Replicated (1)** | Any worker — all endpoints via env vars | ### Security / Identity diff --git a/changelog/changelog-2026-05-31.md b/changelog/changelog-2026-05-31.md new file mode 100644 index 0000000..e9fdfe0 --- /dev/null +++ b/changelog/changelog-2026-05-31.md @@ -0,0 +1,88 @@ +# Changelog -- 2026-05-31 Fleet PXE + PegaProx Deployment + +**Date:** 2026-05-31 +**Author:** F.R.I.D.A.Y. +**Scope:** PXE remastered ISOs, PegaProx deployment, PVE node registration + +--- + +## Changes Made + +### 1. iVentoy Proxmox ISO Remastering + +All four Proxmox VE 9.2 auto-install ISOs were remastered with: +- Embedded per-node answer URLs: `http://192.168.10.15:8080/pve/answers/mkNN.toml` +- UEFI `gfxmode` locked to `1024x768` (removed `640x480` fallback) +- Per-ISO answer files: `mk33.toml`, `mk34.toml`, `mk39.toml`, `mk42.toml` + +**Verification:** +- `strings /opt/iventoy/iso/proxmox-mkNN-auto.iso | grep 192.168.10.15` confirmed embedded URLs +- `xorriso -cpx` extraction confirmed `gfxmode=1024x768` on all 4 ISOs + +### 2. PegaProx Deployment on MK7 + +Deployed PegaProx Proxmox cluster manager to MK7 Swarm: +- Compose file: `/tmp/pegaprox_swarm.yml` +- Ports: `5000` (HTTPS), `5001` (VNC WebSocket), `5002` (SSH WebSocket) +- Publish mode: `host` (WebSocket incompatible with Swarm ingress) +- Network: `traefik-public` overlay +- SSL: Self-signed cert auto-generated (`CN=PegaProx`) + +**Verification:** +- `docker stack deploy -c /tmp/pegaprox_swarm.yml pegaprox` succeeded +- Container healthy, API responding on `https://192.168.7.7:5000` +- Default login: `pegaprox` / `admin` (forces password change) + +### 3. PVE Node Registration in PegaProx + +Three nodes added to PegaProx cluster: + +| Node | PegaProx ID | Host | Status | +|------|-------------|------|--------| +| MK-33 | `726eb477` | `192.168.7.33` | running | +| MK-34 | `df6f5e5d` | `192.168.7.34` | running | +| MK-39 | `9711704b` | `192.168.7.39` | running | + +**API Notes Learned:** +- `host` field must be **bare IP only** (no `:8006`) +- CSRF protection requires `X-Requested-With: XMLHttpRequest` +- `/api/clusters` endpoint used for registration + +### 4. Documentation Updates + +Updated files: +- `fleet/admin-cheat-sheet.md` -- Added PegaProx section, updated node statuses, added iVentoy remastering notes +- `procedures/pega-prox-deploy.md` -- New procedure for deploying PegaProx on Swarm +- `procedures/iventoy-remaster-procedure.md` -- New procedure for remastering PVE ISOs +- `changelog/2026-05-31-pxe-pegaprox-deployment.md` -- This file + +### 5. iVentoy Pro Upgrade -- Pending + +Status: Awaiting private repo link from vendor. Current installation uses iVentoy Free. Pro upgrade may simplify per-node provisioning (per-MAC ISO binding feature expected). + +--- + +## Remaining Work + +- MK-42: Not yet PXE-booted or installed +- PegaProx: Admin password change required (user in progress) +- iVentoy Pro: Upgrade pending vendor repo link +- LXC/cloud-init automation: Terraform templates for Docker Swarm restoration (next phase) +- Traefik DNS record: `pegaprox.ai.home` routing pending Traefik deployment on MK7 + +--- + +## Service Impact + +| Service | Status | Notes | +|---------|--------|-------| +| iVentoy PXE | Ready | 4 remastered ISOs registered | +| PegaProx | Online | 3 PVE nodes connected | +| MK-33 | Online | PVE installed, registered | +| MK-34 | Online | PVE installed, registered | +| MK-39 | Online | PVE installed, registered | +| MK-42 | Offline | Pending PXE boot | + +--- + +*End of changelog* diff --git a/fleet/admin-cheat-sheet.md b/fleet/admin-cheat-sheet.md new file mode 100644 index 0000000..0a3efc6 --- /dev/null +++ b/fleet/admin-cheat-sheet.md @@ -0,0 +1,206 @@ +# Iron Legion Fleet Admin Cheat Sheet + +Generated: 2026-05-31 +Maintainer: F.R.I.D.A.Y. (Hermes Agent) + +--- + +## Quick Access Links + +| Service | URL / Endpoint | Notes | +|---------|---------------|-------| +| iVentoy PXE Server | http://192.168.27.205:26000 | Shield WiFi fallback | +| PegaProx | https://192.168.7.7:5000 | PVE Cluster Manager (host mode) | +| Portainer | https://portainer.ai.home | Swarm Manager | +| Traefik Dashboard | https://traefik.ai.home:8080 | Proxy/Router | +| Technitium DNS | https://dns.ai.home:5380 | DNS Server | +| Beszel Monitoring | https://beszel.ai.home | Fleet Metrics | +| Dozzle | https://dozzle.ai.home | Container Logs | +| Homepage | https://home.ai.home | Service Portal | +| Prometheus | https://prometheus.ai.home | Metrics DB | +| Authelia | https://auth.ai.home | SSO Portal | + +--- + +## Fleet Node Inventory + +### Swarm Manager + +- Hostname: mark-vii.ai.home +- Armor Code: MK-7 +- LAN IP: 192.168.7.7 +- Tailscale IP: 100.66.70.51 +- Role: Swarm Manager, DNS, Traefik, Portainer, PegaProx +- CPUs: 18 | RAM: 15 GB | Disk: 916 GB + +### Worker Nodes G9 (Proxmox VE) + +| Armor | Hostname | LAN IP | Tailscale IP | MAC | Status | +|-------|----------|--------|--------------|-----|--------| +| MK-33 | mk33.ai.home | 192.168.7.33 | TBD | E0-51-D8-1C-5D-56 | Online (PVE) | +| MK-34 | mk34.ai.home | 192.168.7.34 | TBD | E0-51-D8-1C-5C-75 | Online (PVE) | +| MK-39 | mk39.ai.home | 192.168.7.39 | TBD | PENDING | Online (PVE) | +| MK-42 | mk42.ai.home | 192.168.7.42 | TBD | PENDING | Not Installed | + +### Utility Nodes + +| Armor | Hostname | LAN IP | Tailscale IP | Role | +|-------|----------|--------|--------------|------| +| Neo | nebuchadnezzar.ai.home | 192.168.192.24 | 100.99.123.16 | Nextcloud AIO, Gitea | +| MK-44 | mark44.ai.home | 192.168.5.214 | TBD | Ollama GPU | +| MK-5 | mark5.ai.home | 192.168.6.5 | TBD | TBD | +| Shield | shield.ai.home | 192.168.10.15 / 192.168.27.205 | - | PXE/iVentoy Server | +| Artemis | artemis.ai.home | 192.168.15.182 | 100.100.97.18 | Discord Gateway | + +### Mission Control + +- Hostname: mission-control.ai.home +- OS: Windows 11 +- Role: Workstation +- Type: Separate physical machine + +--- + +## PegaProx — Proxmox VE Cluster Manager + +| Attribute | Value | +|-----------|-------| +| **Host** | MK7 (192.168.7.7) | +| **Ports** | 5000 (HTTPS UI/API), 5001 (VNC WebSocket), 5002 (SSH WebSocket) | +| **Deploy mode** | Docker Swarm — `host` publish mode | +| **Network** | `traefik-public` overlay | +| **SSL** | Self-signed cert (`CN=PegaProx`, auto-generated) | +| **Default user** | `pegaprox` (password change required on first login) | +| **Cluster IDs** | MK33=`726eb477`, MK34=`df6f5e5d`, MK39=`9711704b` | + +**Admin password must be changed on first login.** + +**API notes:** +- Add cluster: `host` field must be **bare IP only** (no `:8006` — PegaProx appends port internally) +- CSRF protection requires `X-Requested-With: XMLHttpRequest` on state-changing API calls +- Exempt paths: `/api/auth/login`, `/api/auth/setup`, `/api/health` + +--- + +## iVentoy PXE Configuration + +- Server: shield.ai.home -- 192.168.10.15/27 +- WebUI: http://192.168.27.205:26000 +- Subnet: 192.168.10.0/27 +- Pool: 192.168.10.20 to 192.168.10.30 +- MAC Filter: Permit mode +- Edition: **iVentoy Free** (Pro upgrade pending -- private repo link awaited) + +### Registered ISOs + +| ISO | Node | Purpose | +|-----|------|---------| +| proxmox-mk33-auto.iso | MK-33 | PVE 9.2 Auto-Install | +| proxmox-mk34-auto.iso | MK-34 | PVE 9.2 Auto-Install | +| proxmox-mk39-auto.iso | MK-39 | PVE 9.2 Auto-Install | +| proxmox-mk42-auto.iso | MK-42 | PVE 9.2 Auto-Install | +| proxmox-ve_9.2-1.iso | - | Original PVE ISO | +| ubuntu-24.04.3-live-server-amd64.iso | - | Ubuntu Autoinstall | + +### Whitelisted MACs + +- E0-51-D8-1C-5D-CA (Legacy) +- E0-51-D8-1C-5D-5C (Legacy) +- E0-51-D8-1C-5D-56 (MK-33) +- E0-51-D8-1C-5C-75 (MK-34) +- PENDING: MK-39 +- PENDING: MK-42 + +Post-Install: Remove MAC from whitelist. Node boots local disk, gets production IP. + +### ISO Remastering Notes + +All Proxmox auto-install ISOs are **remastered** with: +1. **Embedded answer URL** -- each ISO points to `http://192.168.10.15:8080/pve/answers/mkNN.toml` (server URL hardcoded; node IP assigned by DHCP) +2. **UEFI gfxmode locked** -- strict `1024x768` (fallback `640x480` removed) +3. **Per-ISO answer files** -- `mk33.toml`, `mk34.toml`, `mk39.toml`, `mk42.toml` in `/opt/iventoy/user/answers/` + +> iVentoy Free does NOT support per-MAC ISO binding. Remastered ISOs achieve per-node provisioning via embedded answer URLs. + +--- + +## DNS Records + +### CNAME to traefik.ai.home -- A: 192.168.7.7 + +- artemis.ai.home +- hermes.ai.home +- n8n.ai.home +- pgadmin.ai.home +- portainer.ai.home +- beszel.ai.home +- dozzle.ai.home +- prometheus.ai.home +- homepage.ai.home +- auth.ai.home +- dns.ai.home + +### A Records + +- traefik.ai.home -> 192.168.7.7 +- mk7.ai.home -> 192.168.7.7 +- mk33.ai.home -> 192.168.7.33 +- mk34.ai.home -> 192.168.7.34 +- mk39.ai.home -> 192.168.7.39 +- mk42.ai.home -> 192.168.7.42 +- mark44.ai.home -> 192.168.5.214 +- mark5.ai.home -> 192.168.6.5 +- nebuchadnezzar.ai.home -> 192.168.192.24 +- shield.ai.home -> 192.168.10.15 + +--- + +## SSH Topology + + Portable Host (F.R.I.D.A.Y.) + | + +---> artemis.ai.home via id_ed25519 + | +---> mk7.ai.home via artemis_key + | + +---> shield via jarvis user + | +---> PXE subnet 192.168.10.0/27 + | + +---> mk33-42 via bobby user (legacy subnet) + | + +---> nebuchadnezzar via jarvis user + +Key Files: +- ~/.ssh/id_ed25519 -- bobby@cinnamint +- ~/.ssh/artemis_key -- MK7 jump-host + +--- + +## Armor Codenames + +| Code | Name | System | +|------|------|--------| +| MK-7 | Mark VII | Swarm Manager | +| MK-33 | Silver Centurion | Worker | +| MK-34 | Igor | Worker | +| MK-39 | Starboost | Worker | +| MK-42 | Bones | Worker | +| MK-44 | Hulkbuster | GPU/Ollama | +| MK-5 | Mark 5 | TBD | +| J.A.R.V.I.S. | Judicious Automated... | Dashboard | +| F.R.I.D.A.Y. | Field-Ready Runtime... | Portable Agent | +| A.R.T.E.M.I.S. | Advanced Real-Time... | Discord | +| NEO | Nebuchadnezzar | Nextcloud | +| SHIELD | - | PXE Server | + +--- + +## Notes + +- iVentoy Free does NOT support per-MAC ISO binding. +- Shield PXE subnet isolated via ip_forward=0. +- Mission Control is separate physical machine. +- All *.ai.home resolve via Technitium DNS. +- PegaProx deployed on MK7 Swarm in `host` mode (not routed through Traefik). +- iVentoy Pro upgrade pending -- private repo link awaited from vendor. + +Last updated: 2026-05-31 by F.R.I.D.A.Y. diff --git a/procedures/iventoy-remaster-procedure.md b/procedures/iventoy-remaster-procedure.md new file mode 100644 index 0000000..f6e91d4 --- /dev/null +++ b/procedures/iventoy-remaster-procedure.md @@ -0,0 +1,238 @@ +# Procedure: Remaster Proxmox VE ISOs for iVentoy Auto-Install + +**Scope:** Remaster stock Proxmox VE ISOs with embedded auto-install answer URLs and locked UEFI gfxmode for PXE boot via iVentoy. +**Author:** F.R.I.D.A.Y. +**Date:** 2026-05-31 +**Prerequisites:** Stock Proxmox VE ISO, `xorriso`, Python 3, iVentoy PXE server running. + +--- + +## 1. Overview + +iVentoy Free does NOT support per-MAC ISO binding. To provision each node with its own network config (IP, gateway, etc.), we remaster the stock Proxmox ISO: + +1. Embed an `auto-installer-mode.toml` file pointing to a per-node answer file +2. Lock UEFI `gfxmode` to `1024x768` (remove `640x480` fallback) +3. Each ISO points to its own answer URL: `http://192.168.10.15:8080/pve/answers/mkNN.toml` + +--- + +## 2. Answer File Structure + +### iVentoy Answer Server + +iVentoy runs a built-in HTTP server on `192.168.10.15:8080`. Answer files live in: +``` +/opt/iventoy/user/answers/ +├── mk33.toml +├── mk34.toml +├── mk39.toml +└── mk42.toml +``` + +### Per-Node Answer File Example (`mk33.toml`) + +```toml +[target] +source = "from-dhcp" # Node IP assigned by iVentoy DHCP, NOT hardcoded + +global] +keyboard = "en-us" +timezone = "America/Toronto" + +[network] +iface = "eno1" +address = "192.168.7.33/18" # Static after install +gateway = "192.168.18.1" +dns = "192.168.7.7" + +[root-password] +pwhash = "$y$j9T$YOUR_HASH_HERE" # Pre-hashed password +``` + +> **Important:** The `answer_url` in the embedded `auto-installer-mode.toml` points to the **server** (`192.168.10.15:8080`), not the node IP. The node IP comes from DHCP during PXE boot (`source = "from-dhcp"`). + +--- + +## 3. Remaster Script + +Save as `/tmp/remaster_pve_iso.py`: + +```python +#!/usr/bin/env python3 +""" +Remaster Proxmox VE ISO with embedded auto-install answer URL. +Locks UEFI gfxmode to 1024x768 (removes 640x480 fallback). +""" +import subprocess +import sys +import tempfile +import os +import shutil + +# Node-specific config +NODE = sys.argv[1] # e.g., mk33 +SRC_ISO = sys.argv[2] # e.g., proxmox-ve_9.2-1.iso +DST_ISO = f"proxmox-{NODE}-auto.iso" +ANSWER_URL = f"http://192.168.10.15:8080/pve/answers/{NODE}.toml" + +# Create auto-installer-mode.toml +auto_installer_toml = f"""[proxmox-auto-installer] +answer_url = "{ANSWER_URL}" +""" + +# Work in temp dir +with tempfile.TemporaryDirectory() as tmpdir: + # Extract ISO contents + subprocess.run(["xorriso", "-osirrox", "on", "-indev", SRC_ISO, + "-extract", "/", tmpdir], check=True) + + # Write auto-installer-mode.toml into ISO root + ai_path = os.path.join(tmpdir, "auto-installer-mode.toml") + with open(ai_path, "w") as f: + f.write(auto_installer_toml) + + # Patch grub.cfg: lock gfxmode to 1024x768 only + grub_path = os.path.join(tmpdir, "boot", "grub", "grub.cfg") + if os.path.exists(grub_path): + with open(grub_path, "r") as f: + content = f.read() + # Remove 640x480 fallback + content = content.replace("set gfxmode=1024x768,640x480", + "set gfxmode=1024x768") + with open(grub_path, "w") as f: + f.write(content) + print("Patched grub.cfg: gfxmode locked to 1024x768") + + # Rebuild ISO with same boot properties + subprocess.run([ + "xorriso", "-as", "mkisofs", + "-o", DST_ISO, + "-isohybrid-mbr", os.path.join(tmpdir, "usr", "lib", "ISOLINUX", "isohdpfx.bin"), + "-c", "boot.cat", + "-b", "isolinux/isolinux.bin", + "-no-emul-boot", "-boot-load-size", "4", "-boot-info-table", + "-eltorito-alt-boot", + "-e", "EFI/BOOT/BOOTX64.EFI", + "-no-emul-boot", "-isohybrid-gpt-basdat", + "-r", "-V", f"Proxmox-VE-Auto-{NODE}", + tmpdir + ], check=True) + + print(f"Created: {DST_ISO}") + print(f"Answer URL embedded: {ANSWER_URL}") +``` + +### Usage + +```bash +# On Shield (iVentoy server) +python3 /tmp/remaster_pve_iso.py mk33 /opt/iventoy/iso/proxmox-ve_9.2-1.iso +python3 /tmp/remaster_pve_iso.py mk34 /opt/iventoy/iso/proxmox-ve_9.2-1.iso +python3 /tmp/remaster_pve_iso.py mk39 /opt/iventoy/iso/proxmox-ve_9.2-1.iso +python3 /tmp/remaster_pve_iso.py mk42 /opt/iventoy/iso/proxmox-ve_9.2-1.iso + +# Move to iVentoy ISO directory +mv proxmox-mk33-auto.iso /opt/iventoy/iso/ +mv proxmox-mk34-auto.iso /opt/iventoy/iso/ +mv proxmox-mk39-auto.iso /opt/iventoy/iso/ +mv proxmox-mk42-auto.iso /opt/iventoy/iso/ +``` + +--- + +## 4. In-Place ISO Patching (gfxmode only) + +If you already have remastered ISOs and only need to patch gfxmode: + +```bash +# Extract grub.cfg from ISO, patch, replace in-place +ISO=/opt/iventoy/iso/proxmox-mk33-auto.iso +xorriso -cpx /boot/grub/grub.cfg /tmp/grub.cfg -< /dev/null -- "$ISO" +sed -i 's/set gfxmode=1024x768,640x480/set gfxmode=1024x768/' /tmp/grub.cfg +xorriso -boot_image any replay -map /tmp/grub.cfg /boot/grub/grub.cfg -- "$ISO" +``` + +> The `-boot_image any replay` flag preserves boot properties after file replacement. + +--- + +## 5. Verification + +```bash +# Confirm answer URL is embedded +strings /opt/iventoy/iso/proxmox-mk33-auto.iso | grep "192.168.10.15" +# Expected: http://192.168.10.15:8080/pve/answers/mk33.toml + +# Confirm gfxmode is locked +xorriso -cpx /boot/grub/grub.cfg /tmp/verify.cfg -< /dev/null -- /opt/iventoy/iso/proxmox-mk33-auto.iso +grep gfxmode /tmp/verify.cfg +# Expected: set gfxmode=1024x768 +``` + +--- + +## 6. iVentoy Configuration + +### Web UI +- URL: `http://192.168.27.205:26000` +- Go to **ISO Management** → add remastered ISOs + +### MAC Whitelist (Permit Mode) +Add node MACs to iVentoy whitelist: +``` +E0-51-D8-1C-5D-56 (MK-33) +E0-51-D8-1C-5C-75 (MK-34) +PENDING (MK-39) +PENDING (MK-42) +``` + +Nodes must be in whitelist to PXE boot. + +### DHCP Pool +- Subnet: `192.168.10.0/27` +- Range: `192.168.10.20` to `192.168.10.30` +- Nodes get temporary PXE IPs from this pool during install + +--- + +## 7. Post-Install + +After node installs and reboots: +1. Remove node MAC from iVentoy whitelist (node boots from local disk) +2. Node gets production IP from `/etc/network/interfaces` (set in answer file) +3. Verify: `ping 192.168.7.33` (or appropriate node IP) + +--- + +## 8. iVentoy Pro Upgrade Notes + +> **Status:** Awaiting private repo link from vendor. + +Expected Pro features (to verify upon upgrade): +- Per-MAC ISO binding (may eliminate need for per-node remastered ISOs) +- Additional deployment modes +- Priority support + +When the private repo link is received: +1. Clone the Pro repository +2. Review upgrade documentation in the repo +3. Backup current `/opt/iventoy/` configuration +4. Follow vendor upgrade procedure +5. Test with one node before fleet-wide rollout + +--- + +## Rollback + +```bash +# Remove remastered ISO +rm /opt/iventoy/iso/proxmox-mk33-auto.iso + +# Re-add stock ISO in iVentoy Web UI +# Node will boot stock ISO -- manual install required +``` + +--- + +*Last updated: 2026-05-31* diff --git a/procedures/pega-prox-deploy.md b/procedures/pega-prox-deploy.md new file mode 100644 index 0000000..6ae52c8 --- /dev/null +++ b/procedures/pega-prox-deploy.md @@ -0,0 +1,165 @@ +# Procedure: Deploy PegaProx on Docker Swarm + +**Scope:** Deploy PegaProx (Proxmox VE cluster manager) as a Docker Swarm service on MK7. +**Author:** F.R.I.D.A.Y. +**Date:** 2026-05-31 +**Prerequisites:** MK7 Swarm manager active, `traefik-public` overlay network exists. + +--- + +## 1. Create Swarm Compose File + +Save as `/tmp/pegaprox_swarm.yml` on MK7: + +```yaml +version: "3.8" +services: + pegaprox: + image: pegaprox/pegaprox:latest + deploy: + mode: replicated + replicas: 1 + placement: + constraints: + - node.role == manager + ports: + - target: 5000 + published: 5000 + mode: host + protocol: tcp + - target: 5001 + published: 5001 + mode: host + protocol: tcp + - target: 5002 + published: 5002 + mode: host + protocol: tcp + networks: + - traefik-public + volumes: + - pegaprox-config:/app/config + environment: + - PEGAPROX_DEBUG=0 + +volumes: + pegaprox-config: + driver: local + +networks: + traefik-public: + external: true +``` + +> **Critical:** `mode: host` is required. `ingress` mode breaks WebSocket VNC/SSH consoles because Swarm ingress routing does not support WebSocket upgrade properly. + +--- + +## 2. Deploy Stack + +```bash +ssh jarvis@mk7.ai.home +docker stack deploy -c /tmp/pegaprox_swarm.yml pegaprox +``` + +Verify: +```bash +docker service ls | grep pegaprox +docker ps | grep pegaprox +``` + +--- + +## 3. Verify Service Health + +```bash +# HTTPS API +curl -sk https://192.168.7.7:5000/api/health + +# Check container logs +docker logs $(docker ps -q -f name=pegaprox) +``` + +Expected: `{"status":"ok"}` + +--- + +## 4. First Login & Password Change + +1. Open `https://192.168.7.7:5000` +2. Login with default credentials: + - Username: `pegaprox` + - Password: `admin` +3. System will force password change on first login +4. API returns: `{"security_warning":"DEFAULT_PASSWORD","requires_password_change":true}` + +--- + +## 5. API Notes for Automation + +### CSRF Protection +All state-changing API calls (POST/PUT/PATCH/DELETE) must include: +``` +X-Requested-With: XMLHttpRequest +``` + +Exempt paths (no CSRF header needed): +- `/api/auth/login` +- `/api/auth/setup` +- `/api/auth/oidc/*` +- `/api/auth/check` +- `/api/auth/validate` +- `/api/auth/logout` +- `/api/health` +- `/api/webauthn/auth/begin` + +### Add Cluster +```bash +curl -sk -X POST https://192.168.7.7:5000/api/clusters \ + -b cookies.txt \ + -H "Content-Type: application/json" \ + -H "X-Requested-With: XMLHttpRequest" \ + -d '{ + "name": "MK33", + "host": "192.168.7.33", + "user": "root@pam", + "pass": "YOUR_PVE_PASSWORD" + }' +``` + +> **CRITICAL:** `host` must be **bare IP only**. Do NOT append `:8006`. PegaProx appends the port internally. Supplying `192.168.7.33:8006` causes URL parse failure: `Failed to parse: https://[192.168.7.33:8006]:8006/...` + +--- + +## 6. Backup Volume + +```bash +# Backup PegaProx config + DB +docker run --rm -v pegaprox_pegaprox-config:/src -v /tmp:/dst alpine \ + tar czf /dst/pegaprox-config-$(date +%Y%m%d).tar.gz -C /src . +``` + +--- + +## 7. Known Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| WebSocket VNC/SSH broken | Swarm `ingress` mode strips upgrade headers | Use `mode: host` | +| URL parse error on add-cluster | `:8006` appended to host field | Use bare IP only | +| CSRF 403 on API calls | Missing `X-Requested-With` header | Add header to all state-changing calls | +| Self-signed cert warning | No CA-signed cert deployed | Accept in browser or deploy custom cert | + +--- + +## Rollback + +```bash +ssh jarvis@mk7.ai.home +docker stack rm pegaprox +docker volume rm pegaprox_pegaprox-config # WARNING: destroys all data +``` + +--- + +*Last updated: 2026-05-31*