42 KiB
INFRASTRUCTURE REFERENCE — COMPLETE SYSTEM MAP
Last Updated: 2026-07-06
Owner: Myron Blair — myronblair@outlook.com
TABLE OF CONTENTS
- Network Overview
- Cloud Servers
- On-Premise — Proxmox Hypervisors
- On-Premise — Virtual Machines
- NAS Storage
- Websites (all on DO)
- JARVIS AI System
- Phone System (FusionPBX)
- Networking & VPN
- Backup Systems
- SSH Quick Reference
- Critical Credentials Master List
- Git & Repository Management
1. NETWORK OVERVIEW
INTERNET
│
▼
[Cloudflare CDN] ──────────────────────────────────────────────────────────────
│ (proxied DNS for public sites)
│
├─► [DigitalOcean 165.22.1.228] — CyberPanel/OLS — All websites (7 sites)
│
└─► [FusionPBX 134.209.72.226] — FreeSWITCH PBX (SSH via DO relay)
HOME NETWORK (FortiGate router at 10.48.200.1)
WAN: 97.154.109.245 (dynamic, DDNS: orbisne.fortiddns.com)
│
├─► PVE1 Proxmox 10.48.200.90 (primary hypervisor)
│ ├── VM 101 10.48.200.97 Home Assistant
│ ├── VM 112 10.48.200.33 Jellyfin
│ ├── VM 113 10.48.200.35 MediaStack (Sonarr/Radarr/qBT/Prowlarr)
│ ├── VM 118 10.48.200.18 Homebridge
│ ├── VM 120 10.48.200.110 NovaCPX hosting panel
│ ├── VM 210 10.48.200.210 Ollama (local LLM + vision) — llama3.1:8b, llava:7b
│ └── CT110 10.48.200.19 WireGuard exit container
│
├─► PVE2 Proxmox 10.48.200.91 (secondary hypervisor)
│ └── VM 302 10.48.200.99 NetworkBackup
│
├─► Synology NAS 10.48.200.249 — Media & backup storage
├─► Yealink T48S 10.48.200.2 — Ext 1000 (Myron Blair, Desk)
├─► Yealink T48S 10.48.200.43 — Ext 1001 (Tommy Ivy, Desk)
├─► Yealink AX86R 10.48.200.65 — Ext 1002 (Myron Blair, WiFi Work)
├─► Yealink T57W 10.48.200.3 — External SIP (United Mirror & Glass)
├─► Yealink T57W 10.48.200.83 — Ext 1003 (Kitchen)
└─► Yealink T57W 10.48.200.85 — Ext 1004 (Master Bedroom)
FortiGate Port Forwards:
orbisne.fortiddns.com:8006 → PVE1:8006 (Proxmox web UI)
orbisne.fortiddns.com:8123 → HA:8123 (Home Assistant)
orbisne.fortiddns.com:22 → HA VM:22 (SSH — key only, unreliable)
2. CLOUD SERVERS
2A. DigitalOcean — Main Server
| Field | Value |
|---|---|
| IP | 165.22.1.228 |
| OS | Ubuntu 22.04 LTS |
| Panel | CyberPanel (OpenLiteSpeed) |
| SSH | ssh root@165.22.1.228 — password: Gonewalk1974!@# |
| Purpose | All public websites (7 sites) — webhook deploy for websites |
Key Paths:
-
All sites:
/home/<domain>/public_html/ -
Deploy log: per-site (website deploys only)
-
Watchdog log:
/usr/local/lsws/logs/watchdog.log -
Infra repo:
/opt/infra
Services running:
- OpenLiteSpeed web server (
lsws) — serves all 7 sites - MySQL 8 — all site databases on localhost
- Redis — session/cache
- PHP 8.5 (
lsphp85) — runtime for all sites - Cron jobs: website deploy runner (every 1 min), watchdog (every 5 min)
CyberPanel Web UI: https://165.22.1.228:8090
Login: myron / Joker1974!!!
phpMyAdmin: https://165.22.1.228/phpmyadmin
Login: myron / Joker1974!!!
2B. FusionPBX / FreeSWITCH — PBX Server
| Field | Value |
|---|---|
| IP | 134.209.72.226 |
| OS | Debian (DigitalOcean droplet) |
| SSH | Direct via Tailscale: ssh root@100.74.46.120 — password: Joker1974!@# |
| Direct SSH | Only from: 107.178.2.130 / 97.154.109.245 |
| Purpose | VoIP phone system — handles all inbound/outbound calls |
Web UI: https://fusion.orbishosting.com
Login: admin / fY7XP5swgtpbzrYLhkeVYkA4744
Database: PostgreSQL
User: fusionpbx / Password: pSJaF9mUJqPr4Sj5mwJyRqvCCpc / Host: 127.0.0.1
SIP Trunk: SignalWire
DID: +1 (817) 764-5007
Gateway: signalwire on external profile (port 5080, UDP)
How calls flow:
Caller → SignalWire SIP → FusionPBX:5080 → IVR (ext 900) → Ring extensions
Outbound: Phone → FusionPBX:5080 → SignalWire → PSTN
SSH Relay Command:
sshpass -p 'Gonewalk1974!@#' ssh -o StrictHostKeyChecking=no root@165.22.1.228 \
'sshpass -p "Joker1974!@#" ssh -o StrictHostKeyChecking=no root@134.209.72.226 "COMMAND"'
3. ON-PREMISE — PROXMOX HYPERVISORS
PVE1 — Primary Hypervisor
| Field | Value |
|---|---|
| Local IP | 10.48.200.90 |
| External | orbisne.fortiddns.com (FortiGate DDNS — auto-updates on WAN IP change) |
| OS | Proxmox VE 8.x |
| SSH | ssh root@orbisne.fortiddns.com OR ssh root@10.48.200.90 — password: Joker1974!!! |
| Web UI | https://orbisne.fortiddns.com:8006 — root / Joker1974!!! |
| Purpose | Runs VMs 101, 112, 113, 118, 120, 210, CT110 |
Useful commands:
qm list # list all VMs
qm start/stop/restart <VMID> # control VMs
qm guest exec <VMID> -- bash -c "cmd" # run command inside VM (requires QEMU agent)
JARVIS API Token: root@pam!jarvis=c45b5feb-f9a9-445d-a626-14fbb959f78b
PVE2 — Secondary Hypervisor
| Field | Value |
|---|---|
| Local IP | 10.48.200.91 |
| OS | Proxmox VE 8.x |
| SSH | ssh root@10.48.200.91 — password: Joker1974!!! |
| Web UI | https://10.48.200.91:8006 — root / Joker1974!!! |
| Purpose | Runs VM 302 (NetworkBackup); part of shared Proxmox cluster with PVE1 |
4. ON-PREMISE — VIRTUAL MACHINES
VM 101 — Home Assistant (PVE1)
| Field | Value |
|---|---|
| IP | 10.48.200.97 |
| OS | Ubuntu + Home Assistant OS/Supervised |
| Web UI | http://orbisne.fortiddns.com:8123 — myron / [HA password] |
| SSH | Via HA web terminal only (Settings → Add-ons → Advanced SSH & Web Terminal) |
| Purpose | Smart home automation — 212 entities (lights, switches, scenes, sensors) |
| JARVIS Agent | ID: homeassistant_ha — pushes entity states to JARVIS every 10s |
JARVIS ↔ HA Integration:
- HA custom component at
/config/custom_components/jarvis_agent/ - Pushes all entity state changes to JARVIS
/api/agent/ha_state(debounced 2s) - JARVIS admin toggles → queued in
agent_commandstable → HA executes natively - HA Long-lived Token (Jarvis2):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzNmI0N2I1Njk5ZGQ0MTQ2ODMwZWFmYjZiYTQ1MjJkMSIsImlhdCI6MTc4MDIwMzU5NCwiZXhwIjoyMDk1NTYzNTk0fQ.sYRok-jRDlA4lFgWxLQELcEjkJNGQdprk6ZziLwLtXE
VM 112 — Jellyfin Media Server (PVE1)
| Field | Value |
|---|---|
| IP | 10.48.200.33 |
| OS | Ubuntu 22.04 LTS |
| SSH | ssh root@10.48.200.33 — password: Joker1974!!! (enabled 2026-06-14) |
| Web UI | http://10.48.200.33:8096 |
| Purpose | Media streaming server — Movies and TV shows |
| JARVIS Agent | Not yet installed |
Media Libraries:
- Movies:
/mnt/mediastack/movies— NFS from MediaStack (10.48.200.35:/media/movies) - TV:
/mnt/mediastack/tv— NFS from MediaStack (10.48.200.35:/media/tv)
NFS chain: Jellyfin → MediaStack → Synology NAS (/volume1/video/movies and /volume1/video/tv)
Admin token: 7c0ccf78b91d4b5bafa607f585f24f2d
If library scan needed:
curl -X POST "http://10.48.200.33:8096/Library/Refresh" \
-H "X-Emby-Token: 7c0ccf78b91d4b5bafa607f585f24f2d"
If NFS stale after MediaStack changes:
umount -l /mnt/mediastack/movies && umount -l /mnt/mediastack/tv
mount /mnt/mediastack/movies && mount /mnt/mediastack/tv
VM 113 — MediaStack (PVE1)
| Field | Value |
|---|---|
| IP | 10.48.200.35 |
| OS | Ubuntu 24.04 LTS |
| SSH | Via PVE1: ssh -i /root/.ssh/id_rsa root@10.48.200.35 (no direct access from DO) |
| Purpose | Automated media download pipeline + NFS server to Jellyfin |
| JARVIS Agent | ID: MediaStack_2c00b1b8 |
Services:
| Service | Port | Login | API Key |
|---|---|---|---|
| qBittorrent | :8080 | admin / Joker1974!!! |
— |
| Sonarr | :8989 | admin / Joker1974!!! |
b43e04350a594846b4ee95261c29e9e0 |
| Radarr | :7878 | admin / Joker1974!!! |
53c4268360444feeae5f98c0cc24e0e3 |
| Prowlarr | :9696 | admin / Joker1974!!! |
9d0ce6c5660743b5bf1c7951efc62252 |
All services run as root — required by Synology NFS ACL (only root can write).
VPN: NordVPN — nordlynx WireGuard interface — exit IP 181.214.226.188 (US Dallas)
All download traffic exits via NordVPN. If downloads stall, check: ip rule show for rules 32764/32765.
Media Flow:
IPTorrents (Prowlarr) → Sonarr/Radarr search → qBittorrent download
→ /mnt/nas/video/downloads (NAS)
→ Sonarr/Radarr import → /mnt/nas/video/tv or /mnt/nas/video/movies (NAS)
→ NFS → Jellyfin /mnt/mediastack/movies or /mnt/mediastack/tv
Indexer: IPTorrents via Prowlarr cookie auth
Cookie: uid=2237410; pass=JzLP2niTWxBJAZIU3yvtLbJzD55kdLeB
(Expires — if search fails, log into iptorrents.com, copy uid+pass cookies)
If Radarr/Sonarr shows "0 active indexers":
systemctl stop radarr
sqlite3 /var/lib/radarr/radarr.db "DELETE FROM IndexerStatus WHERE ProviderId=1;"
systemctl start radarr
SSH from DO:
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.90 \
'ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa root@10.48.200.35 "COMMAND"'
VM 118 — Homebridge (PVE1)
| Field | Value |
|---|---|
| IP | 10.48.200.18 |
| OS | Linux |
| SSH | ssh myron@10.48.200.18 — password: Joker1974! |
| Purpose | Apple HomeKit bridge — exposes non-HomeKit devices to Apple Home app |
| JARVIS Agent | ID: homebridge_b57cbaea |
VM 120 — NovaCPX Hosting Panel (PVE1)
| Field | Value |
|---|---|
| IP | 10.48.200.110 |
| OS | Ubuntu 24.04 LTS |
| SSH | ssh root@10.48.200.110 — password: Joker1974!!! (direct, no PVE hop) |
| Purpose | Custom web hosting control panel (cPanel alternative), v1.0.27 |
| JARVIS Agent | ID: novacpx_e3b07264 |
Ports:
| Port | Panel |
|---|---|
| :8880 | User panel |
| :8881 | Reseller panel |
| :8882 | Admin panel |
| :8883 | Roundcube webmail |
Admin: https://10.48.200.110:8882 — admin / Admin2026!
phpMyAdmin: http://10.48.200.110/phpmyadmin
File Paths:
- Web root:
/srv/novacpx/public/ - DB (SQLite):
/var/lib/novacpx/panel.db - Config:
/etc/novacpx/config.ini - Git repo:
/opt/novacpx-src/ - GitHub:
myronblair/novacpx(auto-deploy on push tomain)
VM 210 — Ollama Local LLM + Vision (PVE1)
| Field | Value |
|---|---|
| IP | 10.48.200.210 |
| OS | Ubuntu (cloud image) |
| SSH | ssh root@10.48.200.210 via PVE1 hop — password: Joker1974!!! |
| Purpose | Local AI inference — chat (llama3.1:8b) + vision (llava:7b) |
| API | http://10.48.200.210:11434 (Ollama REST API) |
| JARVIS Agent | ID: ollama-ai_ubuntu |
| Models | llama3.1:8b (chat/Tier 1), llava:7b (vision cascade) |
JARVIS uses this as Tier 1 AI — if Ollama is down, falls back to Groq (cloud).
Vision cascade: Arc Reactor calls Claude first; if Claude credits depleted, falls back to llava:7b via Ollama.
Vision is enabled via: /etc/systemd/system/jarvis-arc.service.d/vision.conf → OLLAMA_VISION_MODEL=llava:7b
VM 302 — NetworkBackup (PVE2)
| Field | Value |
|---|---|
| IP | 10.48.200.99 |
| OS | Ubuntu/Linux |
| SSH | ssh myron@10.48.200.99 — password: Joker1974! (then sudo) |
| Purpose | Network backup storage / backup operations |
| JARVIS Agent | ID: networkbackup_NetworkB |
CT110 — WireGuard Exit Container (PVE1)
| Field | Value |
|---|---|
| IP | 10.48.200.19 / 10.48.200.67 |
| Purpose | Legacy WireGuard exit tunnel to DO (10.200.0.4 via wg-exit) — currently NOT used by MediaStack/Jellyfin |
| Note | MediaStack uses NordVPN directly; Jellyfin uses wg1 peer on MediaStack for NFS only |
5. NAS STORAGE
Synology NAS
| Field | Value |
|---|---|
| IP | 10.48.200.249 |
| Login | nas / Joker1974!!! |
| DSM Web UI | http://10.48.200.249:5000 |
| Purpose | Primary media and download storage |
NFS Share: /volume1/video (exported to MediaStack only)
Directory structure:
/volume1/video/
movies/ ← Radarr imports here; NFS-exported to Jellyfin via MediaStack
tv/ ← Sonarr imports here; NFS-exported to Jellyfin via MediaStack
downloads/ ← qBittorrent downloads here (temp)
incomplete/ ← in-progress torrents
Important: Synology NFS ACL only allows root to write. All services on MediaStack run as root.
6. WEBSITES (ALL ON DO)
All sites are at /home/<domain>/public_html/ on DO (165.22.1.228).
Auto-deploy: Push to main on GitHub → webhook → server pulls in ~1 min.
GitHub PAT: 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 (rotated 2026-07-05 — old PAT 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 was found exposed in .git/config on all 6 original sites and must be treated as compromised/revoked)
jarvis.orbishosting.com — JARVIS AI Dashboard (MOVED TO PVE1 VM 211)
| Field | Value |
|---|---|
| URL | http://jarvis.orbishosting.com (port 80 — old :1972 reference was wrong, corrected 2026-07-04) |
| Path | /var/www/jarvis/ (on JARVIS VM 10.48.200.211) |
| GitHub | myronblair/jarvis |
| Login | myron / Joker1974!!! |
| Purpose | Iron Man-style AI home dashboard with voice control, smart home, media, planner |
See Section 7 for full JARVIS details.
worktracking.orbishosting.com — ChuckCo Time Keeper
| Field | Value |
|---|---|
| URL | https://worktracking.orbishosting.com |
| Path | /home/worktracking.orbishosting.com/public_html/ |
| GitHub | myronblair/chucko (private) |
| Gitea | myron/chucko (pull-mirror of GitHub) |
| Local clone | C:\Users\myron\repos\chucko on admin Windows machine |
| Purpose | Work-tracking app for a flat-rate 5-day (Fri–Thu) work week — self-reported hours via personal secret-URL tokens (no login), single shared admin password, phone-friendly screenshot pages for texting workers/payer |
| Admin URL | https://worktracking.orbishosting.com/admin/login.php — password Joker1974!!! |
| DB | workt_track_db / workt_track_user / ZWCNMRP2N5NVPsghmve5aRS9 |
| Linked from Blair HQ | web.orbishosting.com dashboard's "Websites" card has direct links to the admin login and the all-workers overview page (site-wide token 972f82cbf7832fdb2cffcdcc84129a4af69e30bd) |
| Note | Built 2026-07-05. includes/config.php (DB creds, admin password hash, site token) lives outside public_html/webroot and is intentionally NOT in the git repo. |
| Admin login rate limiting | Added 2026-07-06 — login_attempts table (ip_address, attempts, last_attempt) in workt_track_db; 5 failed attempts locks that IP out for 15 minutes. |
| Code review (2026-07-06) | 5 findings fixed and deployed: w.php mark_paid now rejects any week_start that isn't the true current week (was trusting client input); admin/worker.php no longer double-HTML-escapes the page title; all.php now shows a Paid/Unpaid badge per worker for the displayed week; s.php/p.php/all.php validate the week param before building dates (malformed input used to throw an uncaught DateTime exception); admin login rate-limited (see above). |
tomsjavajive.com — Tom's Java Jive
| Field | Value |
|---|---|
| URL | https://tomsjavajive.com |
| Path | /home/tomsjavajive.com/public_html/ |
| GitHub | myronblair/tomsjavajive |
| Purpose | Coffee shop e-commerce — products, orders, loyalty, wallet, reviews |
| Admin URL | https://tomsjavajive.com/admin/ |
| Admin Login | admin@tomsjavajive.com / Joker1974!!! OR myronblair@outlook.com / Joker1974!!! |
| DB | toms_tjj_db / toms_tjj_user / +60wlPc+55e@gFq4 |
CyberMail API key: sk_live_7f9b0f9a29f6de31a0d229d4af75d56b094ad724fc58a57d |
|
| Email From | noreply@tomsjavajive.com / Toms Java Jive (set in DB settings table) |
epictravelexpeditions.com — Epic Travel Expeditions
| Field | Value |
|---|---|
| URL | https://epictravelexpeditions.com |
| Path | /home/epictravelexpeditions.com/public_html/ |
| GitHub | myronblair/epictravelexpeditions |
| Purpose | Travel booking / expeditions website |
| DB | epic_travel_db (see api/config.php) |
parkerslingshot.epictravelexpeditions.com — Parker Slingshot (OLD)
| Field | Value |
|---|---|
| URL | https://parkerslingshot.epictravelexpeditions.com |
| Path | /home/epictravelexpeditions.com/parkerslingshot/ |
| GitHub | myronblair/parkerslingshot |
| Purpose | Old slingshot rental site (superseded by parkerslingshotrentals.com) |
parkerslingshotrentals.com — Parker Slingshot Rentals (LIVE)
| Field | Value |
|---|---|
| URL | https://www.parkerslingshotrentals.com |
| Path | /home/parkerslingshotrentals.com/public_html/ |
| GitHub | myronblair/parkerslingshotrentals |
| Purpose | Polaris Slingshot rental — bookings, e-signature waiver, admin management |
| Admin | /admin/index.php — admin / Parker2026! |
| DB | park_slingshot / park_slingshotuser / 4@rxg*8kovxCr7w6 |
| Square | Production token: EAAAl3FsAu_2ri8kZE_ENEyi2T_C8HXXm5XQFY6Lbnd8SX6FqYp8J_upUeXNYh7v |
orbishosting.com — Orbis Hosting (Landing Page)
| Field | Value |
|---|---|
| URL | https://orbishosting.com |
| Path | /home/orbishosting.com/public_html/ |
| GitHub | myronblair/orbishosting |
| Purpose | Public landing page for Orbis Hosting brand |
orbis.orbishosting.com — Orbis Hosting Portal
| Field | Value |
|---|---|
| URL | https://orbis.orbishosting.com |
| Path | /home/orbis.orbishosting.com/public_html/ |
| GitHub | myronblair/orbis-hosting-portal |
| Purpose | Customer-facing hosting portal |
tomtomgames.com — TomTom Games
| Field | Value |
|---|---|
| URL | https://tomtomgames.com |
| Path | /home/tomtomgames.com/public_html/ |
| GitHub | myronblair/tomtomgames |
| Purpose | Gaming website |
| DB | tomtom_games_db (see config) |
CyberMail API key: sk_live_7f9b... |
7. JARVIS AI SYSTEM
URL: http://jarvis.orbishosting.com
Files: /var/www/jarvis/ on JARVIS VM (PVE1 VM 211 — 10.48.200.211, 8 cores, 16GB RAM)
DB: jarvis_db — jarvis_user / J4rv1s_Pr0t0c0l_2026!
Login: myron / Joker1974!!!
Admin portal: http://jarvis.orbishosting.com/admin
Security hardening (2026-07-06 code review)
Full front-end + admin panel review found and fixed 8 issues, 2 of them live critical exposures:
- INFRASTRUCTURE-REFERENCE.md was publicly downloadable with zero auth (static nginx path bypassed the admin session check entirely). Fixed: file moved to
/var/www/jarvis-private/INFRASTRUCTURE-REFERENCE.md(ownedwww-data:www-data, mode 640, NOT underpublic_htmlso nginx never serves it directly), and the DOCS tab now downloads it via a new authenticateddocs_downloadaction inadmin/index.phpthat gates on the existingloggedIn()check and streams the file withreadfile(). - Two full backup copies of the 5000-line admin panel (
index.php.bak2,index.php.bak.<date>) were sitting inpublic_html/admin/and downloadable with no auth, exposing the entire admin source/attack surface. Relocated to/root/jarvis-old-backups/(no secrets were found in them, so no credential rotation was needed). esc()(the admin panel's JS HTML-escaper) doesn't escape', so it doesn't protect values embedded inside a single-quoted JS string within anonclickattribute — HTML-decoding happens before the JS parser sees it. Added a properescJs()helper (backslash + quote + newline escaping, then HTML-escape) and applied it to the Network/Alerts/Intents/Custom-News/Calendar-Feeds edit-modalonclickhandlers, which were reachable by e.g. any device on the LAN setting a malicious DHCP/mDNS hostname.- Same class of bug on the front-end dashboard (
assets/js/jarvis-app.js,assets/js/panels/jarvis-agents.js): device names and news article titles/sources were inserted intoinnerHTMLcompletely unescaped — a rogue LAN device or a malicious/compromised news feed could inject script that runs with the logged-in session. AddedescHtml()/escJs()helpers directly injarvis-app.jsand applied them to device names, VM names, agent hostnames, and news content. session.cookie_httponlywas Off server-wide (PHP default), meaning the actual session cookie — not just the app's own bearer token — was readable viadocument.cookiefrom any of the above XSS bugs. Fixed at the PHP-FPM level (/etc/php/8.3/fpm/php.ini):session.cookie_httponly = 1,session.cookie_samesite = Lax,php8.3-fpmrestarted. Verified live:Set-Cookienow includesHttpOnly; SameSite=Lax.api.phphadAccess-Control-Allow-Origin: *— tightened to an explicit allow-list of the real JARVIS origin only, withAccess-Control-Allow-Credentials: trueonly sent when the origin matches.- Two admin actions (Arc Reactor restart/setup) called an undefined function
k()instead of the real JSON responderj(), causing a PHP fatal error even though the underlyingsystemctlcommand still fired. Fixed (verified via direct API test — clean{"ok":true,...}response now). - Calendar feed passwords were stored and returned in plaintext via
cal_feeds_list'sSELECT *. Changed to return ahas_passwordboolean instead of the raw password (the edit UI never actually displayed the password back anyway — write-only field, "leave blank to keep").
All fixes verified via direct API testing (SSH + curl through the login/action flow) since this doesn't have a staging environment. Pushed to myronblair/jarvis master, commit 24bc876.
Architecture (end-to-end)
Voice (browser mic)
→ SpeechRecognition API
→ Wake phrase: "wake up JARVIS" / "daddy's home"
→ "JARVIS [command]" triggers action
→ /api/chat.php (4-tier AI)
Tier 0.7: KB intents / planner (tasks, appointments)
Tier 1: Knowledge Base (MySQL)
Tier 1.5: Ollama (10.48.200.210:11434, llama3.1:8b) — local LLM
Vision: Ollama llava:7b (via Arc Reactor _vision_call cascade)
Tier 2: Groq (cloud, model: compound-beta-mini)
Tier 3: Claude API (Anthropic, fallback)
→ ElevenLabs TTS → browser speaker
Arc Reactor (AI Job Processor)
Service: jarvis-arc (systemd) — port 7474
Runtime: /opt/jarvis-arc/ (Python venv, reactor.py)
Log: /var/log/jarvis/arc.log
Admin button: Workers → Daemons → SETUP (live popup) / RESTART
Vision: Claude → Ollama llava:7b → graceful fallback
Vision config: /etc/systemd/system/jarvis-arc.service.d/vision.conf
systemctl status jarvis-arc
systemctl restart jarvis-arc
journalctl -u jarvis-arc -f
To re-deploy Arc Reactor from source: Use Workers → Daemons → SETUP in JARVIS admin (live log popup shows progress).
Planner: Tasks / Directives / Missions
Admin UI sections backed by real schema + live API — verified working 2026-07-02 (created/read/deleted a test row in each, end-to-end).
Tasks — simple to-do list, stored directly in jarvis_db.
- Table:
tasks(title, notes, category, priority [urgent/high/normal/low], status [pending/in_progress/done/cancelled], due_date, due_time) - API:
task_list(GET),task_save(POST, form-encoded),task_done(POST),task_delete(POST)
Directives — OKR-style goals with key results, stored directly in jarvis_db.
- Tables:
directives(title, description, category, status, priority, target_date) +directive_key_results(directive_id, title, current_value, target_value, unit) +directive_links(directive_id, link_type, link_id — links a directive to a task/etc.) - API:
directive_list,directive_get,directive_save(POST, JSON body viaphp://input, id passed as?id=query param on update),directive_delete
Missions — automation workflows, NOT stored in jarvis_db — proxied through Arc Reactor (port 7474) which owns the mission state.
- Arc Reactor endpoints used by admin:
GET/POST /missions,GET /missions/{id},GET /missions/{id}/runs,PUT/POST /missions/{id},DELETE /missions/{id},POST /missions/{id}/run - JARVIS-side mirror tables exist (
missions,mission_runs,mission_steps) but the admin panel reads/writes live via Arc Reactor's HTTP API, not directly against these tables - API:
mission_list,mission_get,mission_runs,mission_save(POST, JSON body, id as?id=on update),mission_delete,mission_run,mission_toggle - If Arc Reactor is down, these calls return
{"error":"Arc Reactor unreachable"}— checksystemctl status jarvis-arcfirst
As of 2026-07-02: all three tables are empty (0 rows) — features are fully functional, just unused so far.
Deploy Pipeline
Code edit → git push → GitHub webhook → /webhook.php (HMAC verified)
→ /tmp/jarvis-deploy-queue.txt → /usr/local/bin/jarvis-deploy.sh (cron 1min)
→ git pull + PHP syntax check → deploy or auto-revert
Webhook secret: 4c8805f0285214ff0a0602b5880270b935f36a896946c7f1
Agent System
Agents installed on all servers — phone home every 10s (heartbeat) / 30s (metrics).
Registration key: f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518
Install command: curl -sk http://10.48.200.211/install-agent.sh | bash -s <hostname> <linux|proxmox>
Self-Healing Watchdog
/usr/local/bin/jarvis-watchdog.sh — runs every 5 min (root cron on DO)
Restarts: lsws, mysql, redis if down
Restarts offline Proxmox VM agents via qm guest exec
Cron Jobs (DO server)
| Schedule | Script | Purpose |
|---|---|---|
| Every 1 min | jarvis-deploy.sh |
Process GitHub deploy queue |
| Every 3 min | facts_collector.php |
Collect agent metrics, KB facts, site health |
| Every 5 min | stats_cache.php |
Weather, news, Proxmox stats refresh |
| Every 5 min | jarvis-watchdog.sh |
Self-healing: restart dead services |
8. PHONE SYSTEM (FUSIONPBX)
Extensions
| Ext | Name | Phone | IP | SIP Password |
|---|---|---|---|---|
| 1000 | Myron Blair — Desk | Yealink T48S | 10.48.200.2 | Xk9mPw3nQv7rLs2t |
| 1001 | Tommy Ivy — Desk | Yealink T48S | 10.48.200.43 | Tv8xNm4pWq6rZs3k |
| 1002 | Myron Blair — WiFi Work | Yealink AX86R | 10.48.200.65 | yXHaJTwa8rj?$GkrVFQB |
| 1003 | Kitchen | Yealink T57W | 10.48.200.83 | — |
| 1004 | Master Bedroom | Yealink T57W | 10.48.200.85 | — |
| 1010 | Parker County Slingshot | Virtual (voicemail only) | — | — |
| 1011 | Epic Travel Expeditions | Virtual (voicemail only) | — | — |
| 1012 | Tom's Java Jive | Virtual (voicemail only) | — | — |
| 900 | IVR | — | — | (auto-attendant) |
Phone SIP Settings (all phones):
- Server:
134.209.72.226 - Port:
5080 - Transport: UDP
Provisioning URL: https://fusion.orbishosting.com/app/provision/
(Username: provision-master, Password: Joker1974!!!)
Call Flow
Inbound (+18177645007)
→ SignalWire → FusionPBX:5080 (UDP)
→ signalwire-inbound dialplan (catch-all ^.*$)
→ IVR ext 900 (ivr_menu_16k.wav)
→ Routes to extensions 1000/1001/1002/1003/1004
Outbound
→ Phone → FusionPBX:5080
→ signalwire gateway → SignalWire → PSTN
FreeSWITCH CLI Commands
fs_cli -x "sofia status profile external reg" # check registrations
fs_cli -x "sofia xmlstatus gateway" # check SignalWire gateway
fs_cli -x "reloadxml" # reload config (safe)
fs_cli -x "reloadacl" # reload ACL (safe)
# AVOID: sofia profile external restart (drops all phone registrations)
9. NETWORKING & VPN
FortiGate Firewall
- WAN IP: 97.154.109.245 (dynamic)
- DDNS:
orbisne.fortiddns.com(FortiGate auto-updates on IP change) - Blocks: outbound port 53 (DNS) — MediaStack uses PVE1 dnsmasq (10.48.200.90) as resolver → 100.100.100.100
- Upstream DNS (changed 2026-07-05): Network → DNS set to "Specify" mode — Primary
1.1.1.1(Cloudflare), Secondary8.8.4.4(Google). Previously defaulted to the router itself (10.48.200.1)/ISP-provided servers. Admin:https://10.48.200.1:9443—admin / Joker1974!!!. Note:8.8.8.8specifically showed as "Unreachable" during setup (transient — ISP's own DNS servers were also showing high latency at that moment);1.1.1.1/8.8.4.4tested healthy and are what's live now.
Port Forwards:
| External Port | Internal Destination | Purpose |
|---|---|---|
| :8006 | PVE1:8006 | Proxmox web UI |
| :8123 | HA VM:8123 | Home Assistant |
| :22 | HA VM:22 | HA SSH (unreliable) |
WireGuard — Jellyfin ↔ MediaStack
- MediaStack runs WireGuard server on
wg1(port 51820, subnet 10.200.0.1/24) - Jellyfin peer: 10.200.0.3 (active handshake)
- Used for NFS media file access ONLY — not internet VPN
NordVPN — MediaStack Internet Traffic
- Interface:
nordlynxon MediaStack - Exit IP: 181.214.226.188 (US Dallas)
- Policy routing: table 205 (all traffic via nordlynx), managed by
nordvpn-routing.service - Required for IPTorrents access (blocks non-VPN IPs)
10. BACKUP SYSTEMS
JARVIS Database Backup
- Script:
/usr/local/bin/jarvis-backup.sh(also at/var/www/jarvis/deploy/) - Output:
/var/backups/jarvis/jarvis_backup_TIMESTAMP.tar.gz - Log:
/var/backups/jarvis/backup.log - Retention: 7 days (auto-purge)
- Trigger: JARVIS admin → Backups → RUN BACKUP NOW, or run script directly
- DB:
jarvis_db—jarvis_user / J4rv1s_Pr0t0c0l_2026!
DO Server Backup
- Repo:
myronblair/do-server-config - Schedule: Weekly, Sunday 4am
- Launcher:
/usr/local/bin/do-server-backupon DO - Covers: Scripts, systemd units, WireGuard, OLS vhosts, cron, MySQL credentials
- Restore: 8-phase wizard in
restore.sh - DB backups:
jarvis-backup.shruns daily (separate)
Proxmox Config Backup
- Repo:
myronblair/proxmox-config - Schedule: Weekly, Sunday 3am (both PVE1 and PVE2)
- Launcher:
/usr/local/bin/proxmox-backupon each node - Covers: VM .conf files, network, cron, systemd, scripts
- VM disks: Covered by Proxmox Backup Server (PBS)
FusionPBX Backup
- Repo:
myronblair/fusionpbx-config - Schedule: Weekly, Sunday 5am
- Launcher:
/usr/local/bin/fusionpbx-backup - Covers: PostgreSQL dump (gzip, ~29-60MB) + FreeSWITCH configs
- Restore: 10-phase wizard in
restore.sh - Known issue (found 2026-07-05): this repo has grown to ~166MB on GitHub / ~196MB on Gitea because the DB dump gets committed directly into git history on every backup run (3 copies in history as of this writing, each ~60MB) rather than being excluded/rotated. Options not yet decided: gitignore the dump going forward, or purge it from history with
git filter-repo+ force-push (destructive, needs explicit sign-off).
MSP360 Backup Status (Dashboard Integration)
- Client software: MSP360 (CloudBerry) Backup CLI installed on all 6 hosts — PVE1, JARVIS (211), NovaCPX (110), Jellyfin (33), MediaStack (35), Homebridge (18)
- Storage target:
NAS-MSPBackupsdestination → Synology NAS CIFS share, mounted at/mnt/nas-backups/MSPBackups - Mount reliability:
/usr/local/bin/msp360-mount-ensure.sh(cron*/15 * * * *on hosts using the NAS mount) — bind-mounts the MSPBackups subdir onto itself since MSP360's pre-flightmountpointcheck fails on a subdirectory of a CIFS mount otherwise - Collector:
/usr/local/bin/backup-status-collect.shon PVE1 (runs via key-trusted root SSH — PVE1 is the only host with passwordless SSH to all 6 targets; other hosts use password auth viasshpass)- Queries each host's plan via
cbb plan -l(legacy v1 CLI — outputsState:/Last result:fields directly, unlikecbbV2/cbbCommandLineV2which needsplan list -band different parsing) - Writes
/tmp/backup-status.json, thenscps it toroot@10.48.200.110:/home/webacct/public_html/downloads/backup-status.json - Schedule: daily
0 6 * * *on PVE1 (>> /var/log/backup-status-collect.log)
- Queries each host's plan via
- Dashboard card:
web.orbishosting.com"BACKUP STATUS" card (index.html) fetches/downloads/backup-status.jsonclient-side (loadBackupStatus()), color-codes dots byresult(green=Success, yellow=Warning, red=Fail, cyan=Running, gray=unknown) - JSON schema:
{"updated": "<ISO8601 UTC>", "hosts": [{"name","ip","state","result"}, ...]} - Homebridge (2026-07-04): dropped MSP360 entirely. After extensive troubleshooting (RAM starvation, a bug where its account scanned every other host's shared backup data, missing bind-mount depths, CIFS tuning, a full plan recreation) Homebridge's MSP360 agent kept failing with a false "storage drive not mounted" error at a consistent ~60-75s mark, root cause never conclusively identified (survived every environmental fix, looked like an app-level bug tied to any custom/non-default account path). Since Homebridge (VM 118) was already being backed up successfully every night by the cluster-wide Proxmox vzdump job (
backup-aa6b1890-23c0, all VMs, 21:00 daily, keep-last=3, toSynologyProxstorage), MSP360 was stopped/disabled on Homebridge (systemctl disable msp360-backup.service msp360-backupWA.service) and removed from the dashboard collector's per-host MSP360 check. The collector now reads Homebridge's status directly from/mnt/pve/SynologyProx/dump/vzdump-qemu-118-*.vma.zston PVE1 instead of querying an in-guest agent. - Known state (2026-07-04): 4/5 remaining MSP360 hosts report
Warning, NovaCPX reportsFail— plan-level result, not investigated further; worth checking each host's MSP360 GUI/log for root cause if backups need to be trusted for restore. Homebridge reportsSuccessvia Proxmox.
11. SSH QUICK REFERENCE
# DO (main web server)
sshpass -p 'Gonewalk1974!@#' ssh -o StrictHostKeyChecking=no root@165.22.1.228
# FusionPBX (must relay via DO)
sshpass -p 'Gonewalk1974!@#' ssh root@165.22.1.228 \
'sshpass -p "Joker1974!@#" ssh root@134.209.72.226 "CMD"'
# PVE1 (direct or via DDNS)
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@orbisne.fortiddns.com
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.90
# PVE2
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.91
# MediaStack (via PVE1)
sshpass -p 'Joker1974!!!' ssh root@10.48.200.90 \
'ssh -i /root/.ssh/id_rsa root@10.48.200.35 "CMD"'
# Jellyfin (direct, password enabled 2026-06-14)
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.33
# NovaCPX (direct)
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.110
# Ollama / Homebridge / NetworkBackup (myron user, then sudo)
sshpass -p 'Joker1974!' ssh myron@10.48.200.95 # Ollama
sshpass -p 'Joker1974!' ssh myron@10.48.200.18 # Homebridge
sshpass -p 'Joker1974!' ssh myron@10.48.200.99 # NetworkBackup
# Run command inside VM via Proxmox (requires QEMU agent installed)
sshpass -p 'Joker1974!!!' ssh root@10.48.200.90 \
'qm guest exec 210 -- bash -c "CMD"'
Password fallback order: Joker1974!@# → Joker1974!!! → Joker1974!
12. CRITICAL CREDENTIALS MASTER LIST
SSH / Root Access
| System | User | Password | Notes |
|---|---|---|---|
| DO (165.22.1.228) | root | Gonewalk1974!@# |
Main web server |
| FusionPBX (134.209.72.226) | root | Joker1974!@# |
Via DO relay |
| PVE1 (10.48.200.90) | root | Joker1974!!! |
Also via DDNS |
| PVE2 (10.48.200.91) | root | Joker1974!!! |
|
| MediaStack (10.48.200.35) | root | key only | Via PVE1 (/root/.ssh/id_rsa) |
| Jellyfin (10.48.200.33) | root | Joker1974!!! |
Enabled 2026-06-14 |
| NovaCPX (10.48.200.110) | root | Joker1974!!! |
Direct SSH works |
| Ollama / Homebridge / Backup VMs | myron | Joker1974! |
Then sudo |
Web Panels & Admin
| System | URL | User | Password |
|---|---|---|---|
| CyberPanel | https://165.22.1.228:8090 | myron | Joker1974!!! |
| phpMyAdmin (DO) | https://165.22.1.228/phpmyadmin | myron | Joker1974!!! |
| Proxmox PVE1 | https://orbisne.fortiddns.com:8006 | root | Joker1974!!! |
| Proxmox PVE2 | https://10.48.200.91:8006 | root | Joker1974!!! |
| JARVIS | http://jarvis.orbishosting.com | myron | Joker1974!!! |
| JARVIS Admin | http://jarvis.orbishosting.com/admin | myron | Joker1974!!! |
| ChuckCo Time Keeper Admin | https://worktracking.orbishosting.com/admin/login.php | — | Joker1974!!! |
| FusionPBX | https://fusion.orbishosting.com | admin | fY7XP5swgtpbzrYLhkeVYkA4744 |
| Home Assistant | http://orbisne.fortiddns.com:8123 | myron | (HA password) |
| NovaCPX Admin | https://10.48.200.110:8882 | admin | Admin2026! |
| Jellyfin | http://10.48.200.33:8096 | — | token: 7c0ccf78b91d4b5bafa607f585f24f2d |
| qBittorrent | http://10.48.200.35:8080 | admin | Joker1974!!! |
| Sonarr | http://10.48.200.35:8989 | admin | Joker1974!!! |
| Radarr | http://10.48.200.35:7878 | admin | Joker1974!!! |
| Prowlarr | http://10.48.200.35:9696 | admin | Joker1974!!! |
| Synology NAS | http://10.48.200.249:5000 | nas | Joker1974!!! |
| Parker Slingshot Admin | https://parkerslingshotrentals.com/admin | admin | Parker2026! |
| TJJ Admin | https://tomsjavajive.com/admin | admin@tomsjavajive.com OR myronblair@outlook.com |
Joker1974!!! |
Databases
| Site | DB Name | DB User | DB Password |
|---|---|---|---|
| JARVIS | jarvis_db |
jarvis_user |
J4rv1s_Pr0t0c0l_2026! |
| Tom's Java Jive | toms_tjj_db |
toms_tjj_user |
+60wlPc+55e@gFq4 |
| Parker Slingshot Rentals | park_slingshot |
park_slingshotuser |
4@rxg*8kovxCr7w6 |
| Epic Travel | epic_travel_db |
(see config.php) | (see config.php) |
| Epic/Parker Slingshot | epic_parkersling |
epic_parkersling |
Joker1974!!! |
| NovaCPX | SQLite: /var/lib/novacpx/panel.db |
— | — |
| ChuckCo Time Keeper | workt_track_db |
workt_track_user |
ZWCNMRP2N5NVPsghmve5aRS9 |
| FusionPBX | PostgreSQL | fusionpbx |
pSJaF9mUJqPr4Sj5mwJyRqvCCpc |
| MySQL root (DO) | — | root | b71e5c1a8c7457541b9c1db822de37adfa271926a38b6c20 |
API Keys
| Service | Key |
|---|---|
| GitHub PAT | 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 (rotated 2026-07-05, scopes repo+workflow) |
| JARVIS Agent Registration | f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518 |
| Proxmox API Token | root@pam!jarvis=c45b5feb-f9a9-445d-a626-14fbb959f78b |
| HA Long-lived Token | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzNmI0N2I1Njk5ZGQ0MTQ2ODMwZWFmYjZiYTQ1MjJkMSIsImlhdCI6MTc4MDIwMzU5NCwiZXhwIjoyMDk1NTYzNTk0fQ.sYRok-jRDlA4lFgWxLQELcEjkJNGQdprk6ZziLwLtXE |
| Sonarr API | b43e04350a594846b4ee95261c29e9e0 |
| Radarr API | 53c4268360444feeae5f98c0cc24e0e3 |
| Prowlarr API | 9d0ce6c5660743b5bf1c7951efc62252 |
| Jellyfin Admin Token | 7c0ccf78b91d4b5bafa607f585f24f2d |
| Square (Parker) Production | EAAAl3FsAu_2ri8kZE_ENEyi2T_C8HXXm5XQFY6Lbnd8SX6FqYp8J_upUeXNYh7v |
| Square App ID (Parker) | sq0idp-YSM7BU9IVyOWSzpeP-0nzQ |
| Webhook HMAC Secret | 4c8805f0285214ff0a0602b5880270b935f36a896946c7f1 |
SIP / Phone
| Extension | Name | SIP Password |
|---|---|---|
| 1000 | Myron Blair — Desk (10.48.200.2) | Xk9mPw3nQv7rLs2t |
| 1001 | Tommy Ivy — Desk (10.48.200.43) | Tv8xNm4pWq6rZs3k |
| 1002 | Myron Blair — WiFi Work (10.48.200.65) | yXHaJTwa8rj?$GkrVFQB |
| 1003 | Kitchen (10.48.200.83) | — |
| 1004 | Master Bedroom (10.48.200.85) | — |
| 1010 | Parker County Slingshot (voicemail only) | — |
| 1011 | Epic Travel Expeditions (voicemail only) | — |
| 1012 | Tom's Java Jive (voicemail only) | — |
13. GIT & REPOSITORY MANAGEMENT
GitHub (myronblair, 26 private repos as of 2026-07-05) is the permanent/source-of-truth storage. Gitea (gitea.orbishosting.com, hosted on the Synology NAS, login myron / Joker1974!!!) mirrors it one-way — GitHub → Gitea only, via pull-mirrors triggered by POST /api/v1/repos/<owner>/<repo>/mirror-sync. Never push directly to a Gitea remote.
5 repos are Gitea-only by design, never pushed to GitHub (deliberately kept off a third-party cloud service since they hold real credentials): fortigate-config, infra-private, jarvis-secrets, msp360-config, proxmox-secrets.
Local clones live on the admin Windows machine at C:\Users\myron\repos\ (currently chucko, web-dashboard — more cloned there as needed). Periodic maintenance: git gc --aggressive --prune=now to keep loose objects packed.
Per-site deploy pattern (the 7 DO-hosted sites + jarvis + web-dashboard): .git metadata is relocated outside the public webroot (e.g. /home/<site>/git-data with a gitdir: pointer file left in public_html/.git) so .git itself is never web-accessible, while git commands run normally from inside public_html. Most sites deploy via a GitHub webhook → queue file → cron puller (~1 min); chucko (ChuckCo Time Keeper) currently has no auto-deploy hook — pushes are manual (SSH in, git pull/push directly).
Known repo-hygiene issue: fusionpbx-config bloated to ~166-196MB from repeatedly committing a large DB dump straight into history — see Section 10.
This document contains sensitive credentials. Store securely and do not share.