Skip to main content
Admin Modules

Server Management

Unified server management hub with config-driven detail pages, provider-aware inventory, and a persisted infrastructure job queue for safe background actions

February 28, 2026

Server Management

The server management module (v3.1.0) is the unified hub for all infrastructure servers. The index page is a premium glass morphism dashboard with search/filter, network-colored cards, toast notifications, copy-IP-on-click, loading skeletons, import/export JSON, and a persisted background job queue for safety-gated operations. Detail pages are config-driven via D1 database fields — a single dynamic [slug].astro page renders server-specific content based on server_type, with live Proxmox API integration for hypervisors.

Pages

RouteContent
/admin/serversGlass morphism card grid, import/export, stats bar
/admin/servers/Meridian-HostFull Unraid admin (6 tabs, dedicated page)
/admin/servers/[slug]Dynamic detail page — renders based on server_type from D1

Architecture

Config-Driven Detail Pages

In v2.x, each server had a hardcoded .astro file (Tarn-Host.astro, Izar-Host.astro, etc.) with static VM listings and service data baked into source code. In v3.0.0, a single [slug].astro catch-all replaces all 5 static pages with a dynamic page driven by three D1 fields:

FieldPurposeExample
slugURL-friendly identifier for routingTarn-Host, sentinel
server_typeDetermines which template to renderproxmox, vps, gateway
proxy_endpointAPI proxy path for live data (nullable)/api/Tarn-Host-adminbox/servers/Tarn-Host

Astro’s file-based routing gives named files priority over [slug], so Meridian-Host.astro still serves the Meridian-Host page — it’s too specialized (6 tabs, Docker management, rTorrent controls, SSH keys) to merge into the generic template.

Server Types

TypeRenderingLive DataExample Servers
proxmoxNode status, tabbed VMs/CTs/Storage, actionsYes (15s refresh)Tarn-Host, Izar-Host
unraidFalls through to Meridian-Host dedicated pageN/AMeridian-Host
vpsService grid from D1NoSentinel VPS
vmService grid from D1NoWorkbench
gatewayServices grouped by categoryNoAltair-Link
genericBasic service grid + notesNoAny new server

Open Source Friendly

All server data lives in D1, not in source code. Open source users see an empty server list and can import their own infrastructure via JSON. The private/servers-seed.json file is gitignored — only the owner’s instance has pre-populated data.

Infrastructure Control Queue (Phase 1)

Server operations that can be destructive now flow through a persisted queue table (infra_jobs) instead of immediate direct mutation from the browser.

Why Queue It

  • Enables background processing and clear audit history for infra actions
  • Adds a safety delay before execution (10 seconds)
  • Supports explicit status tracking (queued, running, succeeded, failed, cancelled)
  • Decouples UI click events from execution timing

Current Queued Action

  • delete_server — remove a server record from D1 after typed confirmation (DELETE <server-name>)

Queue APIs

RouteMethodPurpose
/api/admin/infra/inventoryGETUnified inventory across server records with provider/type/network summaries
/api/admin/infra/jobsGETList recent infra jobs and opportunistically process due queued jobs
/api/admin/infra/jobsPOSTQueue or manage jobs (delete_server, process_queue, cancel_job)

Index Page (/admin/servers)

Premium glass morphism server cards with 3px gradient top accent. Each card shows server icon with hover glow, name, network badge, service count, clickable IP addresses (monospace, copy-on-click), OS, and notes.

Card Design

  • Glass morphism: rgba(15,23,42,0.65) background, thin border, 14px radius
  • 3px gradient top accent bar (network color → transparent) via ::before pseudo-element
  • Network colors: Milky Way=#06b6d4 (cyan), Andromeda=#8b5cf6 (purple), External=#f97316 (orange), Cloud=#f59e0b (amber)
  • Hover: translateY(-3px) + multi-layer network-colored box-shadow + icon glow
  • Click any IP address to copy to clipboard (toast confirmation)
  • Smooth service collapse/expand via max-height CSS transition
  • Collapsible services section with mini-grid of service chips (icon + name + port)

Search & Filter

  • Real-time search across server names, IPs, OS, service names, and ports
  • Network filter pills: All, Milky Way, Andromeda, External, Cloud
  • “No results” state when search/filter returns empty

Toast Notifications

Slide-in notifications replace all alert() calls. Four types: info (cyan), success (green), error (red), warning (amber). Uses bouncy cubic-bezier(0.34, 1.56, 0.64, 1) entrance animation.

Loading Skeleton

Shimmer-animated skeleton cards display while the API response loads, preventing layout shift.

CSS Architecture

Uses <style is:global> because all cards are dynamically created via JavaScript innerHTML — Astro’s default scoped styles don’t apply to dynamic elements. All class names prefixed with srv- to prevent collisions with CosmicLayout globals.

Action Pills

ButtonColorAction
Web UI (cyan)#06b6d4Opens web_ui_url in new tab (Proxmox, Unraid, etc.)
Terminal (purple)#8b5cf6Opens terminal — new tab for CF tunnel URLs, iframe for direct IPs
Details (green)#10b981Navigate to /admin/servers/<slug> detail page
Edit (amber)#f59e0bOpen edit modal
Delete (red)#ef4444Queue typed-confirm deletion (DELETE <name>) with safety delay

Stats Bar

Five stat chips: Total Servers, Milky Way count, Andromeda count, External count, Total Services.

Import / Export

  • Import: Paste JSON array or upload .json file → validates structure → POSTs each server to API → progress bar
  • Export: Downloads all servers as Arcturus-Prime-servers-YYYY-MM-DD.json (strips id, timestamps)
  • User-specific seed data belongs in private/servers-seed.json (gitignored)

Servers with a slug field in D1 get a green “Details” pill button. No hardcoded slug list — the index page reads the slug field directly from the API response.

Add/Edit Modal

The modal form includes all server fields:

FieldTypeNotes
NameText (required)Display name
IP AddressTextPrimary IP
Tailscale IPTextVPN IP
OSTextOperating system
NetworkSelectMilky Way, Andromeda, External, Cloud
IconTextFont Awesome class (e.g., fa-solid fa-server)
ColorColor picker + hexAccent color
Terminal URLTextURL for terminal access
Web UI URLTextDirect web UI link
SlugTextURL identifier for detail page
Server TypeSelectproxmox, unraid, vps, vm, gateway, generic
Proxy EndpointTextAPI proxy path for live data
NotesTextareaFree-text notes
ServicesDynamic listName, port, type, icon, color, URLs, auth, category

Dynamic Detail Page (/admin/servers/[slug])

Shared Elements (All Server Types)

Every detail page includes:

  • Back link to /admin/servers
  • Server header: icon (with color tint), name, network badge, OS badge
  • Copy-on-click IPs: Primary IP and Tailscale IP as monospace badges
  • Connection indicator (servers with proxy_endpoint): green pulsing “Connected”, amber “Connecting”, red “Offline”
  • Web UI button: Opens web_ui_url in new tab (shown if set)
  • Terminal button: Opens terminal_url — new tab for CF tunnel URLs (*.Arcturus-Prime.com), direct for IP-based URLs
  • Notes: Italic subtitle from D1 notes field
  • Toast notifications: Same system as index page

Proxmox Type

For servers with server_type: "proxmox" and a proxy_endpoint, the page fetches live data from the Tarn-Host-adminbox API via the Arcturus-Prime proxy.

Node Status Cards

Four stat cards in a responsive grid:

CardDataVisual
CPUPercentage + core countCyan progress bar
RAMUsed / Total (formatted)Purple progress bar
UptimeDays + hours or hours + minutesText only
Load1m / 5m / 15m averagesText only

Tabbed Content

Three tabs: VMs, Containers, Storage.

VMs/Containers tabs show entity cards with:

  • VMID badge (e.g., “VM 101”, “CT 203”)
  • Name
  • Status badge (running=green, stopped=red, paused=amber)
  • CPU and RAM mini-bars with percentages
  • Uptime (running VMs/CTs only)
  • Action buttons: Start (green), Stop (red), Restart (amber)
  • Running entities have green left border accent; stopped entities are dimmed

Storage tab shows storage pool cards with:

  • Pool name (monospace) and type badge
  • Utilization bar (green < 75%, amber < 90%, red > 90%)
  • Used/Total/Free breakdown
  • Critical warning banner when > 90% used

Auto-Refresh

  • Data refreshes every 15 seconds via setInterval
  • Interval cleared on astro:before-preparation (View Transitions cleanup)
  • After VM/CT actions (start/stop/restart), data refreshes after 3-second delay

Graceful Degradation

When the Tarn-Host-adminbox API is unavailable:

  • Connection indicator turns red (“Offline”)
  • Troubleshooting banner appears with:
    • Health check command: curl http://10.42.0.199:8095/api/health
    • Tunnel check: cloudflared tunnel info
    • Env var check: TITAN_ADMINBOX_TOKEN
  • Falls back to showing static services from D1 data

API Endpoints Used

EndpointReturns
GET {proxy_endpoint}Node status: cpu, maxcpu, mem, maxmem, uptime, load
GET {proxy_endpoint}/vmsVM list: vmid, name, status, cpu, mem, maxmem, uptime
GET {proxy_endpoint}/containersContainer list: same fields as VMs
GET {proxy_endpoint}/storageStorage pools: storage, type, total, used, avail
POST {proxy_endpoint}/{vms|containers}/{vmid}/{action}Power action: start, stop, shutdown, reboot

All memory/storage values in bytes. CPU usage 0-1 scale. Uptime in seconds.

Gateway Type

For server_type: "gateway" servers, services from D1 are grouped by category field with section headers:

CategoryIconColor
Monitoringheart-pulse#22c55e
Dev Toolsscrewdriver-wrench#06b6d4
Admingauge-high#8b5cf6
Storagefolder-open#f59e0b
Communicationcomments#f472b6
Networkingglobe#3b82f6

Each category section shows a title with icon, service count badge, and a grid of service cards.

VPS / VM / Generic Types

These types render a flat service grid from D1 services JSON. Each service card shows:

  • Icon (from service icon field or default cube)
  • Name
  • Port chip (monospace)
  • Type chip
  • Auth indicator (lock icon + method)
  • Dev URL link (blue)
  • Prod URL link (green)

CSS Architecture

Uses <style is:global> with sd- prefix (server-detail). Glass morphism cards matching the index page aesthetic. Responsive breakpoints at 768px and 480px.

Meridian-Host (/admin/servers/Meridian-Host)

Full Unraid admin page with 7 tabs. This is a dedicated page (not using the dynamic [slug] system) due to its specialized functionality. All API calls go through the /api/mm-Arcturus-Prime/* proxy which injects the Bearer token server-side.

Tabs

TabContent
OverviewArray status, disk temps, cache/parity info, alerts
DownloadsrTorrent active/completed/stopped torrents, add/remove/start/stop controls
ContainersDocker container list, start/stop/restart, status indicators
VMsVirtual machine list, start/stop, state display
StorageSMART data, share listing, disk utilization bars
SSHKey management, authorized_keys display
LogsSyslog and container log viewer (added v3.2.0)

Logs Tab (v3.2.0)

Live log viewer for host syslog and per-container logs. All data fetched via /api/mm-Arcturus-Prime/logs/* endpoints.

Controls toolbar:

  • Source selector — “System Log (syslog)” plus all managed containers (populated dynamically from /api/mm-Arcturus-Prime/logs/containers)
  • Filter input — text filter with 400ms debounce, sanitized server-side (alphanumeric + spaces + dashes only)
  • Line count — 100, 200 (default), 500, or 1000
  • Auto-refresh checkbox — 5-second interval when enabled
  • Refresh button — manual fetch

Log output:

  • Monospace <pre> block, dark background (#0a0a14), max-height 70vh with vertical scroll
  • Color-coded lines: errors (red), warnings (amber), normal (gray/white)
  • Auto-scrolls to bottom on new data
  • Container list is loaded lazily on first Logs tab click

Backend endpoints used:

EndpointPurpose
GET /api/mm-Arcturus-Prime/logs/syslog?lines=N&filter=textHost syslog via nsenter, max 1000 lines
GET /api/mm-Arcturus-Prime/logs/containersList managed container names for source dropdown
GET /api/mm-Arcturus-Prime/logs/container/<name>?lines=NContainer logs via Docker socket API

Container logs use the Docker multiplexed stream format (8-byte header per frame) parsed server-side. The Docker CLI is not available inside the Alpine container — logs are fetched via the Docker Unix socket API directly.

Technical Details

  • Extracts CF JWT from Cf-Access-Jwt-Assertion header in frontmatter
  • Passes JWT to client via define:vars={{ cfJwt }}
  • Auto-refreshes data every 15 seconds (cleanup on astro:before-preparation)
  • Log auto-refresh timer also cleaned up on astro:before-preparation
  • All DOM operations use null-safe ?. checks
  • Toast notification system for user feedback
  • Connection status indicator in header

Terminal Behavior

Terminal buttons detect the URL type and choose the appropriate method:

URL PatternBehaviorReason
*.Arcturus-Prime.comOpens in new tabCF Access sets X-Frame-Options: DENY, blocking iframes
Direct IP (e.g., http://10.42.0.x:7681)Iframe overlay (dev mode)No CF Access restrictions

API

Server CRUD

/api/admin/servers — requires admin authentication.

MethodActionParameters
GETList all servers
GETGet single by ID?id=xxx
GETGet single by slug?slug=xxx
POSTCreate serverServer JSON body
PUTUpdate serverServer JSON body with id
DELETEDelete server?id=xxx

Infrastructure Queue & Inventory

/api/admin/infra/inventory and /api/admin/infra/jobs — requires admin authentication.

/api/admin/infra/jobs actions:

  • delete_server — queue a safe delete
  • process_queue — force a queue processing pass
  • cancel_job — cancel queued (not running) jobs

Proxy Routes

RouteTargetAuth
/api/mm-Arcturus-Prime/[...path]Meridian-Host container (192.168.20.50:8888)MM_ARGOBOX_TOKEN
/api/Tarn-Host-adminbox/[...path]Tarn-Host-adminbox (10.42.0.199:8095)TITAN_ADMINBOX_TOKEN

Both proxies inject Bearer tokens server-side. Dev mode uses direct IPs; prod uses CF tunnel URLs.

Database Schema

Table servers — migrations: 0003_servers_table.sql, 0007_add_web_ui_url.sql, 0015_server_detail_fields.sql

ColumnTypeDescription
idTEXT PKUUID
nameTEXTServer display name
ipTEXTPrimary IP address
tailscale_ipTEXTTailscale VPN IP (nullable)
osTEXTOperating system
networkTEXTNetwork name (Milky Way/Andromeda/External/Cloud)
iconTEXTFont Awesome icon class
colorTEXTAccent color hex
terminal_urlTEXTURL for terminal access (nullable)
web_ui_urlTEXTDirect web UI link (nullable)
slugTEXT UNIQUEURL identifier for detail page routing (nullable)
server_typeTEXTDetail page template: proxmox, unraid, vps, vm, gateway, generic
proxy_endpointTEXTAPI proxy path for live data (nullable)
notesTEXTFree-text notes (nullable)
servicesTEXTJSON array of service objects

Service Object Schema

Each entry in the services JSON array:

{
  "name": "Gitea",
  "port": 3000,
  "type": "Git Hosting",
  "icon": "fa-brands fa-git-alt",
  "color": "#609926",
  "devUrl": "http://10.42.0.199:3000",
  "prodUrl": "https://gitea.Arcturus-Prime.com",
  "auth": "OAuth",
  "category": "dev-tools"
}

Required Environment Variables

VariablePurpose
ADMIN_DBD1 database binding
MM_ARGOBOX_URLMeridian-Host container base URL
MM_ARGOBOX_TOKENBearer token for MM proxy auth
TITAN_ADMINBOX_URLTarn-Host-adminbox base URL
TITAN_ADMINBOX_TOKENBearer token for Tarn-Host-adminbox proxy auth

Version History

VersionDateChanges
1.0.02026-02-21Initial server CRUD with card grid
2.0.02026-02-28Glass morphism overhaul, import/export, 6 static detail pages
3.0.02026-02-28Dynamic [slug].astro replaces 5 static pages, live Proxmox API, D1-driven config
3.1.02026-02-28Infrastructure control queue, typed-confirm delete, glass morphism polish
3.2.02026-03-01Logs tab on Meridian-Host page — syslog + per-container log viewer with auto-refresh
adminserversinfrastructureMeridian-Hostproxmoxunraidsentinelworkbench