diff --git a/DASHBOARD_AS_CODE.md b/DASHBOARD_AS_CODE.md new file mode 100644 index 0000000..4502061 --- /dev/null +++ b/DASHBOARD_AS_CODE.md @@ -0,0 +1,260 @@ +# 🏗️ Dashboard as Code for Homarr + +Homarr 1.0 stores data in SQLite, but there are ways to work with it programmatically. + +--- + +## Option 1: JSON Export/Import (Recommended) + +Homarr 1.0+ supports exporting/importing boards as JSON. + +### How to Export Your Current Board +``` +1. Go to Manage → Boards +2. Click on a board +3. Click "Export" button +4. Download JSON file +``` + +### JSON Structure Example + +Here's a complete board JSON you can import: + +```json +{ + "name": "Main Dashboard", + "description": "Public dashboard with news and links", + "backgroundImage": "", + "backgroundImageAttachment": "fixed", + "backgroundImageRepeat": "no-repeat", + "backgroundImageSize": "cover", + "colorScheme": "dark", + "customCss": "/* Paste CSS from custom-boards.css here */", + "items": [ + { + "type": "clock", + "x": 0, + "y": 0, + "width": 2, + "height": 2, + "options": { + "showDate": true, + "timeFormat": "24" + } + }, + { + "type": "weather", + "x": 2, + "y": 0, + "width": 2, + "height": 2, + "options": { + "location": "Stockholm, Sweden", + "unit": "celsius" + } + }, + { + "type": "rss", + "x": 0, + "y": 2, + "width": 4, + "height": 3, + "options": { + "feedUrls": [ + "https://selfh.st/rss/", + "https://noted.lol/rss/", + "https://feeds.fireside.fm/selfhosted/rss" + ], + "postsLimit": 10, + "enableRtl": false, + "descriptionLineClamp": 3, + "hideDescription": false + } + }, + { + "type": "rss", + "x": 4, + "y": 2, + "width": 4, + "height": 3, + "options": { + "feedUrls": [ + "https://www.bleepingcomputer.com/feed/", + "https://feeds.feedburner.com/TheHackersNews", + "https://krebsonsecurity.com/feed/" + ], + "postsLimit": 10, + "descriptionLineClamp": 2 + } + }, + { + "type": "app", + "x": 0, + "y": 5, + "width": 1, + "height": 1, + "options": { + "appId": "gmail-id" + } + }, + { + "type": "app", + "x": 1, + "y": 5, + "width": 1, + "height": 1, + "options": { + "appId": "github-id" + } + } + ], + "visibility": "public", + "layout": { + "columnCount": 8 + } +} +``` + +### How to Import +``` +1. Manage → Boards +2. Click "Import" button +3. Upload JSON file +4. Review and confirm +``` + +--- + +## Option 2: SQLite Database Editing (Advanced) + +Homarr stores everything in `/opt/homarr/appdata/db/homarr.db` + +### Access the Database +```bash +# SSH to your server +docker exec -it homarr sh + +# Install sqlite3 +apk add sqlite3 + +# Open database +sqlite3 /appdata/db/homarr.db + +# View tables +.tables + +# View boards +SELECT * FROM Board; + +# View apps +SELECT * FROM App; +``` + +### Key Tables +| Table | Purpose | +|-------|---------| +| `Board` | Board definitions | +| `Section` | Board sections/items | +| `App` | App definitions | +| `Integration` | Integration configs | + +--- + +## Option 3: API Approach (Scripting) + +Homarr has internal APIs you can script against: + +### Get Board Data +```bash +# Get all boards +curl http://localhost:7575/api/boards + +# Get specific board +curl http://localhost:7575/api/boards/main-dashboard +``` + +### Create Board via API +```bash +# This requires authentication cookie/session +# You'd need to extract from browser DevTools + +curl -X POST http://localhost:7575/api/boards \ + -H "Content-Type: application/json" \ + -H "Cookie: your-auth-cookie" \ + -d '{ + "name": "Auto Created Board", + "visibility": "public" + }' +``` + +--- + +## Option 4: Pre-built JSON Files (I Can Create These) + +I can create complete JSON files for you to import! + +### Board 1: Main Dashboard JSON +**File:** `boards/main-dashboard.json` + +### Board 2: System Monitor JSON +**File:** `boards/system-overview.json` + +### Board 3: Infrastructure JSON +**File:** `boards/infrastructure.json` + +You would: +1. Download these JSON files +2. Import each one in Homarr +3. Done! + +--- + +## What I Can Do For You + +### Option A: Create Importable JSON Files +I'll create complete JSON files for each board: +- ✅ Main Dashboard (with RSS feeds, clock, weather) +- ✅ System Overview (full-screen Dash.) +- ✅ Infrastructure (with all your apps) +- ✅ Media Center (if needed) + +**You just import them!** + +### Option B: Create SQL Scripts +Generate SQL INSERT statements to directly populate the database. + +### Option C: Step-by-Step Copy/Paste +Provide exact values to enter in each field. + +--- + +## Which Option Do You Want? + +| Option | Effort For You | Effort For Me | Best For | +|--------|---------------|---------------|----------| +| **A - JSON Import** | Low (just import) | Medium | Quick setup | +| **B - SQL Script** | Low (run script) | Medium | Automation | +| **C - Copy/Paste** | Medium | Low | Learning | + +--- + +## Tell Me: + +1. **Which boards** do you want me to build? + - Main Dashboard (public) + - System Overview (private) + - Infrastructure (private) + - Media Center (private) + - News Hub (public) + +2. **Which method?** + - JSON import files + - SQL script + - Copy/paste guide + +3. **Your details:** + - Location (for weather) + - Apps you want included (from the 60+ list) + - RSS feed preferences + +I'll build them for you! 🚀 diff --git a/boards/README.md b/boards/README.md new file mode 100644 index 0000000..2c94d60 --- /dev/null +++ b/boards/README.md @@ -0,0 +1,114 @@ +# 📦 Pre-Built Dashboard JSON Files + +These JSON files are ready to import into Homarr! + +## Available Boards + +| File | Description | Visibility | +|------|-------------|------------| +| `main-dashboard.json` | Public dashboard with RSS feeds, clock, weather, quick links | Public | +| `system-overview.json` | Full-screen Dash. system monitoring | Private | +| `infrastructure.json` | Server management tools with small Dash. widget | Private | + +--- + +## How to Import + +### Method 1: Homarr Import Feature (If Available) + +``` +1. Manage → Boards → Import +2. Select JSON file +3. Review and confirm +``` + +### Method 2: Manual Import via Database (Advanced) + +```bash +# Copy JSON to container +docker cp boards/main-dashboard.json homarr:/tmp/ + +# Access container +docker exec -it homarr sh + +# The JSON structure needs to be inserted into SQLite +# This requires converting to SQL INSERT statements +``` + +### Method 3: Use as Reference (Easiest) + +Open these JSON files and copy the settings into Homarr UI manually. + +--- + +## Before Importing + +### Update These Values in JSON: + +1. **Server IP addresses:** + - Replace `YOUR-SERVER-IP` with your actual IP + - Replace `lemonlink.eu` with your domain + +2. **Weather location:** + - In `main-dashboard.json`, change `"Stockholm, Sweden"` to your location + +3. **RSS feeds:** + - Add/remove feeds as desired + +--- + +## Board Layouts + +### Main Dashboard Layout (8 columns) +``` +Row 0: [Clock 2x2] [Weather 2x2] [Search 4x1] +Row 2: [RSS Homelab 3x4] [RSS Cyber 3x4] [RSS Tech 2x4] +Row 6: [Gmail] [GitHub] [Reddit] [YouTube] [Discord] +Row 7: [Proxmox] [Portainer] [Plex] [Nextcloud] [Vaultwarden] +``` + +### System Overview Layout (12 columns) +``` +Row 0: [Dash. iFrame 12x8 - Full Screen] +``` + +### Infrastructure Layout (8 columns) +``` +Row 0: [Dash. iFrame 8x3] +Row 3: [Proxmox] [Portainer] [TrueNAS] [Pi-hole] [AdGuard] [NPM] [UniFi] [Tailscale] +Row 4: [Grafana] [Prometheus] [Uptime] [Netdata] [WireGuard] +``` + +--- + +## Customization + +Edit the JSON files to: +- Change app URLs +- Add/remove apps +- Adjust widget positions (x, y) +- Resize items (width, height) +- Add custom CSS + +--- + +## Apps Included + +### Main Dashboard +External: Gmail, GitHub, Reddit, YouTube, Discord +Internal: Proxmox, Portainer, Plex, Nextcloud, Vaultwarden + +### Infrastructure +Proxmox, Portainer, TrueNAS, Pi-hole, AdGuard, NPM, UniFi, Tailscale, Grafana, Prometheus, Uptime Kuma, Netdata, WireGuard + +--- + +## Need More Boards? + +I can create additional boards: +- Media Center (Plex, Sonarr, Radarr, etc.) +- Development (GitLab, Jenkins, Registry) +- Smart Home (Home Assistant, Node-RED) +- News Hub (RSS only) + +Just ask! 🚀 diff --git a/boards/infrastructure.json b/boards/infrastructure.json new file mode 100644 index 0000000..4d106a4 --- /dev/null +++ b/boards/infrastructure.json @@ -0,0 +1,260 @@ +{ + "name": "Infrastructure", + "description": "Server and network management tools", + "visibility": "private", + "backgroundImage": "", + "colorScheme": "dark", + "layout": { + "columnCount": 8 + }, + "items": [ + { + "id": "dash-small", + "type": "iframe", + "x": 0, + "y": 0, + "width": 8, + "height": 3, + "options": { + "embedUrl": "http://YOUR-SERVER-IP:3001", + "name": "System Overview" + } + }, + { + "id": "app-proxmox", + "type": "app", + "x": 0, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "proxmox" + } + }, + { + "id": "app-portainer", + "type": "app", + "x": 1, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "portainer" + } + }, + { + "id": "app-truenas", + "type": "app", + "x": 2, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "truenas" + } + }, + { + "id": "app-pihole", + "type": "app", + "x": 3, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "pihole" + } + }, + { + "id": "app-adguard", + "type": "app", + "x": 4, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "adguard" + } + }, + { + "id": "app-npm", + "type": "app", + "x": 5, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "nginx-proxy-manager" + } + }, + { + "id": "app-unifi", + "type": "app", + "x": 6, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "ubiquiti" + } + }, + { + "id": "app-tailscale", + "type": "app", + "x": 7, + "y": 3, + "width": 1, + "height": 1, + "options": { + "appId": "tailscale" + } + }, + { + "id": "app-grafana", + "type": "app", + "x": 0, + "y": 4, + "width": 1, + "height": 1, + "options": { + "appId": "grafana" + } + }, + { + "id": "app-prometheus", + "type": "app", + "x": 1, + "y": 4, + "width": 1, + "height": 1, + "options": { + "appId": "prometheus" + } + }, + { + "id": "app-uptime", + "type": "app", + "x": 2, + "y": 4, + "width": 1, + "height": 1, + "options": { + "appId": "uptime-kuma" + } + }, + { + "id": "app-netdata", + "type": "app", + "x": 3, + "y": 4, + "width": 1, + "height": 1, + "options": { + "appId": "netdata" + } + }, + { + "id": "app-wireguard", + "type": "app", + "x": 4, + "y": 4, + "width": 1, + "height": 1, + "options": { + "appId": "wireguard" + } + } + ], + "apps": [ + { + "id": "proxmox", + "name": "Proxmox", + "iconUrl": "proxmox", + "href": "https://proxmox.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "portainer", + "name": "Portainer", + "iconUrl": "portainer", + "href": "https://portainer.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "truenas", + "name": "TrueNAS", + "iconUrl": "truenas", + "href": "https://truenas.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "pihole", + "name": "Pi-hole", + "iconUrl": "pihole", + "href": "https://pihole.lemonlink.eu/admin", + "behavior": "newTab" + }, + { + "id": "adguard", + "name": "AdGuard", + "iconUrl": "adguard", + "href": "https://adguard.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "nginx-proxy-manager", + "name": "NPM", + "iconUrl": "nginx-proxy-manager", + "href": "https://npm.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "ubiquiti", + "name": "UniFi", + "iconUrl": "ubiquiti", + "href": "https://unifi.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "tailscale", + "name": "Tailscale", + "iconUrl": "tailscale", + "href": "https://login.tailscale.com/admin", + "behavior": "newTab" + }, + { + "id": "grafana", + "name": "Grafana", + "iconUrl": "grafana", + "href": "https://grafana.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "prometheus", + "name": "Prometheus", + "iconUrl": "prometheus", + "href": "https://prometheus.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "uptime-kuma", + "name": "Uptime Kuma", + "iconUrl": "uptime-kuma", + "href": "https://uptime.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "netdata", + "name": "Netdata", + "iconUrl": "netdata", + "href": "https://netdata.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "wireguard", + "name": "WireGuard", + "iconUrl": "wireguard", + "href": "https://wg.lemonlink.eu", + "behavior": "newTab" + } + ] +} diff --git a/boards/main-dashboard.json b/boards/main-dashboard.json new file mode 100644 index 0000000..ebd1ce6 --- /dev/null +++ b/boards/main-dashboard.json @@ -0,0 +1,309 @@ +{ + "name": "Main Dashboard", + "description": "Public dashboard with news, weather, and quick links", + "visibility": "public", + "backgroundImage": "", + "backgroundImageAttachment": "fixed", + "backgroundImageRepeat": "no-repeat", + "backgroundImageSize": "cover", + "colorScheme": "dark", + "customCss": "/* See custom-boards.css in repo */", + "layout": { + "columnCount": 8 + }, + "items": [ + { + "id": "clock-widget", + "type": "clock", + "x": 0, + "y": 0, + "width": 2, + "height": 2, + "options": { + "showDate": true, + "dateFormat": "full", + "timeFormat": "24", + "is24HourFormat": true + } + }, + { + "id": "weather-widget", + "type": "weather", + "x": 2, + "y": 0, + "width": 2, + "height": 2, + "options": { + "location": "Stockholm, Sweden", + "unit": "celsius" + } + }, + { + "id": "search-widget", + "type": "search", + "x": 4, + "y": 0, + "width": 4, + "height": 1, + "options": {} + }, + { + "id": "rss-homelab", + "type": "rss", + "x": 0, + "y": 2, + "width": 3, + "height": 4, + "options": { + "feedUrls": [ + "https://selfh.st/rss/", + "https://noted.lol/rss/", + "https://feeds.fireside.fm/selfhosted/rss" + ], + "postsLimit": 10, + "enableRtl": false, + "descriptionLineClamp": 3, + "hideDescription": false, + "name": "Homelab News" + } + }, + { + "id": "rss-cyber", + "type": "rss", + "x": 3, + "y": 2, + "width": 3, + "height": 4, + "options": { + "feedUrls": [ + "https://www.bleepingcomputer.com/feed/", + "https://feeds.feedburner.com/TheHackersNews", + "https://krebsonsecurity.com/feed/" + ], + "postsLimit": 10, + "enableRtl": false, + "descriptionLineClamp": 2, + "hideDescription": false, + "name": "Cybersecurity" + } + }, + { + "id": "rss-tech", + "type": "rss", + "x": 6, + "y": 2, + "width": 2, + "height": 4, + "options": { + "feedUrls": [ + "https://news.ycombinator.com/rss", + "https://techcrunch.com/feed/" + ], + "postsLimit": 8, + "enableRtl": false, + "descriptionLineClamp": 2, + "hideDescription": true, + "name": "Tech News" + } + }, + { + "id": "app-gmail", + "type": "app", + "x": 0, + "y": 6, + "width": 1, + "height": 1, + "options": { + "appId": "gmail" + } + }, + { + "id": "app-github", + "type": "app", + "x": 1, + "y": 6, + "width": 1, + "height": 1, + "options": { + "appId": "github" + } + }, + { + "id": "app-reddit", + "type": "app", + "x": 2, + "y": 6, + "width": 1, + "height": 1, + "options": { + "appId": "reddit" + } + }, + { + "id": "app-youtube", + "type": "app", + "x": 3, + "y": 6, + "width": 1, + "height": 1, + "options": { + "appId": "youtube" + } + }, + { + "id": "app-discord", + "type": "app", + "x": 4, + "y": 6, + "width": 1, + "height": 1, + "options": { + "appId": "discord" + } + }, + { + "id": "app-proxmox", + "type": "app", + "x": 0, + "y": 7, + "width": 1, + "height": 1, + "options": { + "appId": "proxmox" + } + }, + { + "id": "app-portainer", + "type": "app", + "x": 1, + "y": 7, + "width": 1, + "height": 1, + "options": { + "appId": "portainer" + } + }, + { + "id": "app-plex", + "type": "app", + "x": 2, + "y": 7, + "width": 1, + "height": 1, + "options": { + "appId": "plex" + } + }, + { + "id": "app-nextcloud", + "type": "app", + "x": 3, + "y": 7, + "width": 1, + "height": 1, + "options": { + "appId": "nextcloud" + } + }, + { + "id": "app-vaultwarden", + "type": "app", + "x": 4, + "y": 7, + "width": 1, + "height": 1, + "options": { + "appId": "vaultwarden" + } + } + ], + "apps": [ + { + "id": "gmail", + "name": "Gmail", + "description": "Email", + "iconUrl": "gmail", + "href": "https://mail.google.com", + "behavior": "newTab", + "network": { + "enabled": true, + "timeout": 2000 + } + }, + { + "id": "github", + "name": "GitHub", + "description": "Code Repository", + "iconUrl": "github", + "href": "https://github.com", + "behavior": "newTab" + }, + { + "id": "reddit", + "name": "Reddit", + "description": "Social News", + "iconUrl": "reddit", + "href": "https://reddit.com", + "behavior": "newTab" + }, + { + "id": "youtube", + "name": "YouTube", + "description": "Video Platform", + "iconUrl": "youtube", + "href": "https://youtube.com", + "behavior": "newTab" + }, + { + "id": "discord", + "name": "Discord", + "description": "Chat", + "iconUrl": "discord", + "href": "https://discord.com", + "behavior": "newTab" + }, + { + "id": "proxmox", + "name": "Proxmox", + "description": "Virtualization", + "iconUrl": "proxmox", + "href": "https://proxmox.lemonlink.eu", + "behavior": "newTab", + "network": { + "enabled": true + } + }, + { + "id": "portainer", + "name": "Portainer", + "description": "Docker Management", + "iconUrl": "portainer", + "href": "https://portainer.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "plex", + "name": "Plex", + "description": "Media Server", + "iconUrl": "plex", + "href": "https://plex.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "nextcloud", + "name": "Nextcloud", + "description": "Cloud Storage", + "iconUrl": "nextcloud", + "href": "https://cloud.lemonlink.eu", + "behavior": "newTab" + }, + { + "id": "vaultwarden", + "name": "Vaultwarden", + "description": "Password Manager", + "iconUrl": "vaultwarden", + "href": "https://vault.lemonlink.eu", + "behavior": "newTab" + } + ] +} diff --git a/boards/system-overview.json b/boards/system-overview.json new file mode 100644 index 0000000..7cee743 --- /dev/null +++ b/boards/system-overview.json @@ -0,0 +1,29 @@ +{ + "name": "System Overview", + "description": "Full-screen system monitoring with Dash.", + "visibility": "private", + "backgroundImage": "", + "backgroundImageAttachment": "fixed", + "backgroundImageRepeat": "no-repeat", + "backgroundImageSize": "cover", + "colorScheme": "dark", + "customCss": "/* Full-screen iframe styling */\n[data-dash-component=\"widget-iframe\"] {\n border-radius: 24px !important;\n overflow: hidden !important;\n box-shadow: 0 25px 80px rgba(0,0,0,0.6) !important;\n}", + "layout": { + "columnCount": 12 + }, + "items": [ + { + "id": "dash-iframe", + "type": "iframe", + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "options": { + "embedUrl": "http://YOUR-SERVER-IP:3001", + "name": "System Monitor" + } + } + ], + "apps": [] +}