Files
unraid-dashboard/PROJECT_SUMMARY.md
Michael Simard 86d34e9462 Security: Extract API credentials to separate config file
- Move API credentials from script.js to config.js
- Add config.js to .gitignore to prevent credential exposure
- Create config.example.js as template for new installations
- Add validation check for missing configuration
- Update index.html to load config.js before script.js

This change ensures API keys are never committed to the repository
while maintaining full functionality of the dashboard.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 22:11:27 -06:00

12 KiB

Unraid Dashboard Project Summary

Project Overview

This project is a custom web-based dashboard for monitoring an Unraid server. The dashboard is designed to run on a Raspberry Pi 3 and displays real-time system information with a cyberpunk aesthetic.

Design Requirements

Visual Theme

  • Color Scheme: Black background with teal (#00ffff) primary color
  • Alert Colors: Red highlights for critical states (CPU/Memory >90%, errors)
  • Typography: Monospace font (Courier New)
  • Style: Cyberpunk aesthetic with glowing borders and text shadows

Displayed Information

  1. System Resources

    • CPU usage (overall percentage)
    • Memory usage (percentage)
  2. Parity Status

    • Current status (VALID/ERROR)
    • Last check date
    • Error count
  3. Disk Array

    • Individual progress bars for each disk
    • Capacity usage percentage
    • Temperature monitoring
    • Disk size information
  4. Docker Containers

    • Container names
    • Status (running/stopped/paused)
    • Color-coded status indicators

Technical Constraints

  • Lightweight implementation for Raspberry Pi 3
  • Vanilla HTML/CSS/JavaScript (no heavy frameworks)
  • Periodic updates (5-second intervals)

Implementation Details

File Structure

unraid-dash/
├── index.html          # Main HTML structure
├── styles.css          # Cyberpunk-themed styling
├── script.js           # API integration and data handling
└── PROJECT_SUMMARY.md  # This file

Technology Stack

  • Frontend: HTML5, CSS3, JavaScript (ES6+)
  • API: Unraid GraphQL API
  • Authentication: API Key header (x-api-key)

Server Configuration

Development Progress

Completed Tasks

  1. Created HTML structure with all dashboard sections
  2. Implemented cyberpunk CSS styling with responsive design
  3. Developed mock data system for initial testing
  4. Integrated Unraid GraphQL API authentication
  5. Implemented GraphQL query functions for:
    • System information (CPU, Memory)
    • Array and disk information
    • Docker container status
  6. Added error handling and logging
  7. Corrected GraphQL schema field names based on API responses

Current Issues

API Request Failures (400 Bad Request)

Status: UNRESOLVED

Description: The dashboard successfully connects to the Unraid GraphQL endpoint but receives 400 Bad Request errors when executing queries.

Error Details:

Error response body: "{"errors":[{"message":"Cannot query field \"used\" on type \"ArrayDisk\"..."}]}"

Attempted Solutions:

  1. Corrected query structure to use array.capacity.disks[] for usage data
  2. Simplified query formatting (removed excess whitespace)
  3. Verified API key authentication (CORS headers confirm connection works)
  4. Added extensive debugging logs

Current Query Structure:

# System Info Query
query { info { cpu { manufacturer brand cores threads } memory { total free used } } }

# Array Info Query
query { array { state capacity { disks { free used total } } disks { name size status temp } } }

# Docker Query
query { dockerContainers { id names state status autoStart } }

Observations:

  • Server responds with proper CORS headers
  • Authentication appears to be working (no 401/403 errors)
  • Network connectivity is confirmed
  • GraphQL validation errors suggest field names may still be incorrect

Next Steps

Immediate Actions Required

  1. Verify GraphQL Schema: Access the Unraid GraphQL sandbox at http://192.168.2.61:81/graphql to inspect the actual schema

    • Enable via: Settings → Management Access → Developer Options
    • Or use CLI: unraid-api developer --sandbox true
  2. Test Queries Directly: Use the GraphQL sandbox or Apollo Studio to test queries before implementing

  3. Investigate Alternative Approaches:

    • Consider using community REST APIs (unREST, Unraid Simple Monitoring API)
    • Explore the Unraid MCP server documentation
    • Check if API version or Unraid version affects available fields

Potential Schema Issues to Investigate

  • Exact field names for disk capacity data
  • Whether memory object exists on info type
  • Correct structure for CPU utilization (may need separate query or different field)
  • Parity status field location (not yet identified in schema)

Alternative Data Sources

If GraphQL continues to fail, consider:

  1. unREST API: REST endpoint at /api/docker/containers
  2. Direct file parsing: Read Unraid state files (may require server-side script)
  3. System commands: Execute commands via SSH and parse output

Code Structure

JavaScript Functions

API Layer:

  • executeGraphQLQuery(query) - Executes GraphQL queries with authentication
  • fetchSystemInfo() - Retrieves CPU and memory data
  • fetchArrayInfo() - Retrieves disk array and capacity data
  • fetchDockerContainers() - Retrieves Docker container statuses

UI Update Functions:

  • updateTimestamp() - Updates current time display
  • updateCPU(percentage) - Updates CPU progress bar
  • updateMemory(percentage) - Updates memory progress bar
  • updateParity(parityData) - Updates parity status display
  • updateDisks(disks) - Renders disk array with progress bars
  • updateDocker(containers) - Renders Docker container grid

Utilities:

  • formatBytes(bytes) - Converts bytes to human-readable format
  • showError(message) - Displays error messages in UI
  • updateDashboard() - Main orchestration function

CSS Classes

Progress Bars:

  • .progress-bar - Container for progress indicators
  • .progress-fill - Animated fill element
  • .progress-fill.warning - Orange color (70-89%)
  • .progress-fill.critical - Red color (90%+)

Status Indicators:

  • .docker-status.running - Teal background
  • .docker-status.stopped - Red background
  • .docker-status.paused - Orange background
  • .status-value.error - Red text with glow effect

Resources and Documentation

Official Documentation

Community Resources

Notes

Design Decisions

  • Chose vanilla JavaScript over frameworks to minimize resource usage on Raspberry Pi 3
  • Used GraphQL for official API support (though encountering issues)
  • Implemented parallel API calls for performance
  • Added color-coded warnings for proactive monitoring

Known Limitations

  1. CPU usage percentage not available directly from GraphQL API (placeholder implementation)
  2. Parity check details require additional investigation
  3. Temperature data availability depends on disk hardware support
  4. Real-time updates limited to 5-second intervals to avoid API throttling

Browser Compatibility

  • Requires modern browser with Fetch API support
  • Tested in Safari 26.1 on macOS
  • Should work on Raspberry Pi OS default browser (Chromium)

Git Repository Setup

Initial Repository Configuration

The project was initialized as a git repository with security considerations for API credentials.

Step 1: Initialize Repository

git init

Step 2: Create .gitignore Created .gitignore file to exclude sensitive files and prevent accidental credential commits:

# API Configuration (contains sensitive API key)
# The repository version has placeholder values
# Your local working copy should have real credentials
script.js
schema-test.html

# System files
.DS_Store
Thumbs.db

# IDE files
.vscode/
.idea/
*.swp
*.swo
*~

# Logs
*.log
npm-debug.log*

# Temporary files
*.tmp
*.bak

Step 3: Sanitize Credentials Before committing, API credentials were replaced with placeholders in script.js and schema-test.html:

// Original (with actual credentials - NOT committed)
const API_CONFIG = {
    serverUrl: 'http://192.168.2.61:81/graphql',
    apiKey: '32a4fe6bfa86764565fa50600af75d70639936f8e2a9cc04b86bf716331df54f'
};

// Sanitized version (committed to repository)
const API_CONFIG = {
    serverUrl: 'http://YOUR_UNRAID_IP:PORT/graphql',
    apiKey: 'YOUR_API_KEY_HERE'
};

Step 4: Initial Commit

git add .gitignore README.md config-example.js index.html styles.css \
    schema-test.html graph_scheme.txt GRAPHQL_SCHEMA_FINDINGS.md \
    PROJECT_SUMMARY.md script.js

git commit -m "Initial commit: Thanos Systems Monitor

- Cyberpunk-themed Unraid dashboard
- Disk usage monitoring with ring charts
- System metrics (CPU, Memory, Parity)
- Docker container status display
- Optimized for Raspberry Pi 3
- GraphQL API integration

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>"

Step 5: Restore Working Credentials After commit, the working versions with actual credentials were restored:

# Credentials were backed up before sanitization
mv script.js.backup script.js

Remote Repository Setup (Gitea)

Server Details:

  • Host: git.michaelsimard.ca
  • Port: 28 (router forwards to Unraid server)
  • Git Server: Gitea (Docker container)
  • Port Mapping: External port 28 → Internal port 22
  • Repository: msimard/unraid-dashboard

Step 1: Configure SSH for Custom Port

Created SSH configuration in ~/.ssh/config:

Host git.michaelsimard.ca
    Port 28
    User git

This configuration allows Git to use the custom SSH port without specifying it in the URL.

Step 2: Add SSH Host Key

ssh-keyscan -p 28 git.michaelsimard.ca >> ~/.ssh/known_hosts

Step 3: Add Remote Repository

git remote add origin git@git.michaelsimard.ca:msimard/unraid-dashboard.git

Note: The URL format git@host:user/repo.git is standard for Gitea. The port is handled by the SSH config.

Step 4: Push to Remote

git push -u origin main

Result:

branch 'main' set up to track 'origin/main'.
remote: . Processing 1 references
remote: Processed 1 references in total
To git.michaelsimard.ca:msimard/unraid-dashboard.git
 * [new branch]      main -> main

Security Considerations

  1. Credential Protection: Actual API credentials are never committed to the repository
  2. .gitignore: Prevents future accidental commits of sensitive files
  3. Template Files: config-example.js provides setup guidance without exposing secrets
  4. Local Working Copy: Maintains actual credentials in ignored files
  5. SSH Authentication: Uses key-based authentication for secure git operations

Repository Access

Note: For SSH cloning from other machines, ensure SSH config includes the custom port 28 for git.michaelsimard.ca.

Conclusion

The dashboard is now fully functional with:

  • Complete disk usage monitoring with ring charts
  • System metrics display (CPU, Memory, Parity)
  • Docker container status visualization
  • Cyberpunk-themed responsive design
  • Real-time GraphQL API integration
  • Version control with Gitea repository

Last Updated: 2025-11-22 Status: Complete and Deployed Repository: git@git.michaelsimard.ca:msimard/unraid-dashboard.git