diff --git a/AGENTS.md b/AGENTS.md index 5fb0308..25af198 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -39,10 +39,10 @@ This is the `tower-of-joy` project - a containerized home server infrastructure - **Stack Management** the portainer (and docker) and NPM services are managed through the core-api service. To maintain settings and configurations of these systems, read the documentation at http://tower-of-joy:8083/docs and prefer to use the api functions over direct reads an edits. **Service Integration Policy:** A service deployment is INCOMPLETE until cross-service integrations are implemented. Every new service MUST be integrated with: -- **Organizr:** Configure service in dashboard (Settings → Tab Editor, Homepage Items) +- **Tatlock UI:** Add service to dashboard configuration - **docs/reference/CONTAINERS.md:** Document the service with full profile and configuration table -Services without monitoring and dashboard integration are considered unfinished and should not be marked as "complete" in STATUS.md or commit messages. +Services without dashboard integration are considered unfinished and should not be marked as "complete" in STATUS.md or commit messages. ## Build & Run Commands @@ -355,11 +355,9 @@ When deploying a NEW service, follow this complete checklist. A deployment is ** - [ ] Document access credentials securely **Phase 3: Cross-Service Integration (MANDATORY)** -- [ ] **Organizr Integration:** - - Add service URL and API token to Organizr (Settings → Tab Editor) - - Enable homepage widgets if supported - - Create service tab for direct access - - Test widget displays data correctly +- [ ] **Tatlock UI Integration:** + - Add service to dashboard configuration + - Test service appears correctly in dashboard - [ ] **NPM Integration (if externally accessible):** - Create proxy host entry - Configure SSL with Let's Encrypt @@ -380,7 +378,7 @@ When deploying a NEW service, follow this complete checklist. A deployment is ** **Phase 5: Verification** - [ ] Service accessible at documented URL - [ ] Docker healthcheck shows healthy status -- [ ] Organizr displays service widget/tab correctly +- [ ] Tatlock UI displays service correctly - [ ] Service persists across container restart - [ ] Backups configured (if service has important data) @@ -388,7 +386,7 @@ When deploying a NEW service, follow this complete checklist. A deployment is ** ```bash # 1. Deploy Jellyfin container # 2. Configure Jellyfin settings and add media -# 3. Add Jellyfin to Organizr (homepage widgets + tab) +# 3. Add Jellyfin to Tatlock UI dashboard # 4. Document in CONTAINERS.md # 5. Test all integrations work # ✓ NOW the deployment is complete diff --git a/CONTAINERS.md b/CONTAINERS.md index 2b94b55..f22d262 100644 --- a/CONTAINERS.md +++ b/CONTAINERS.md @@ -1,7 +1,7 @@ # Container Reference - tower-of-joy Infrastructure -> **Last Updated:** 2026-01-02 -> **Total Services:** 28 containers across 22 stacks +> **Last Updated:** 2026-01-03 +> **Total Services:** 26 containers across 20 stacks > **System:** Intel i7-6700, RTX 2080 Ti (11GB VRAM), 64GB RAM, Zorin OS 16.3 --- @@ -17,8 +17,6 @@ | **Redis Shared** | 6379 | N/A (internal) | No | No | - | ✅ Running | | **Ollama** | 11434 | http://192.168.86.149:11434 | LAN | Yes (RTX 2080 Ti) | - | ✅ Running | | **Headscale** | 8085, 9090 | http://192.168.86.149:8085 | LAN | No | - | ✅ Running | -| **Netdata** | 19999 | http://192.168.86.149:19999 | LAN | No | - | ✅ Running | -| **Organizr** | 9999 | https://home.schweitz.net | Internet (SSO) | No | - | ✅ Running | | **Watchtower** | None | N/A (background) | No | No | - | ✅ Running | | **Open WebUI** | 82 | https://webui.schweitz.net | Internet (SSO) | No | - | ✅ Running | | **Core API** | 8083 | http://192.168.86.149:8083 | LAN | No | - | ✅ Running (external) | @@ -37,10 +35,10 @@ | **Paperless-ngx** | 8091 | https://documents.schweitz.net | Internet | No | 8 | ✅ Running | | **ClamAV** | 3310 | N/A (host service) | No | No | - | ✅ Running | | **AdGuard Home** | 53, 3053 | http://dns.schweitz.internal | LAN (DNS) | No | - | ✅ Running | -| **Tatlock UI** | 8092 | http://192.168.86.149:8092 | LAN (future: home.schweitz.net) | No | - | ✅ Running | +| **Tatlock UI** | 9999 | https://home.schweitz.net | Internet | No | - | ✅ Running | ### External Domains (SSL via Let's Encrypt) -- **home.schweitz.net** → Organizr (Protected by Authentik SSO) +- **home.schweitz.net** → Tatlock UI - **media.schweitz.net** → Jellyfin - **cloud.schweitz.net** → Nextcloud - **git.schweitz.net** → Gitea @@ -154,22 +152,13 @@ PostgreSQL Shared is a centralized PostgreSQL 17 database server providing isola | **Resource Limits** | None | | **GPU Required** | No | | **Dependencies** | docker-dataplane network | -| **Databases** | `authentik` (Authentik SSO), `gitea` (Git hosting), `organizr` (Organizr dashboard), `paperless` (Document management), `system_settings` (Central Tatlock settings), `postgres` (default/admin) | -| **Database Users** | `authentik_user`, `gitea_user`, `organizr_user`, `paperless_user`, `settings` (system_settings RW), `postgres` (superuser) | +| **Databases** | `authentik` (Authentik SSO), `gitea` (Git hosting), `paperless` (Document management), `system_settings` (Central Tatlock settings), `postgres` (default/admin) | +| **Database Users** | `authentik_user`, `gitea_user`, `paperless_user`, `settings` (system_settings RW), `postgres` (superuser) | | **Health Check** | `pg_isready -U postgres` (30s interval) | | **Backup Strategy** | `/backups` volume for pg_dump exports | **Initialization**: Databases and users for `authentik` and `gitea` are created by the `postgres-init.sh` script. -**Adding Organizr Database**: - -1. **Generate a secure password** for the `organizr_user`. -2. **In Portainer, navigate to the `postgres-shared` service.** -3. **Go to the "Env" tab and add a new environment variable:** - * **Name:** `ORGANIZR_DB_PASSWORD` - * **Value:** *Your generated password* -4. **Redeploy the `postgres-shared` service.** This will trigger the `postgres-init.sh` script to create the `organizr` database and user. - --- ### Redis Shared @@ -313,80 +302,20 @@ Headscale is a self-hosted control server for Tailscale's mesh VPN protocol, cre --- -## Monitoring Layer - -### Netdata - -Netdata provides comprehensive real-time system performance monitoring with per-second metric collection for CPU, RAM, disk I/O, network traffic, and Docker container resource usage, displaying everything through interactive web dashboards with zero configuration required. It collects thousands of metrics automatically with minimal overhead, offering drill-down capabilities from system-wide views to per-container and per-process analysis. The service maintains short-term metric history in RAM and can stream data to long-term storage backends for historical analysis. - -| Property | Value | -|----------|-------| -| **Image** | `netdata/netdata:latest` | -| **Container Name** | `netdata` | -| **Access URL** | http://192.168.86.149:19999 | -| **External Access** | LAN only (metrics dashboard) | -| **Port Mapping** | 19999:19999 (Web UI) | -| **Network Mode** | Host (for full system visibility) | -| **Restart Policy** | `unless-stopped` | -| **Volume Mounts** | `/proc:/host/proc:ro`, `/sys:/host/sys:ro`, `/var/run/docker.sock:/var/run/docker.sock:ro` | -| **Capabilities** | `SYS_PTRACE`, `apparmor:unconfined` | -| **Resource Limits** | None (monitoring overhead ~1-3% CPU) | -| **GPU Required** | No | -| **Dependencies** | Docker socket (read-only) | -| **Metric Retention** | ~1 hour (RAM-based) | - ---- - -### Organizr - -Organizr serves as a comprehensive unified dashboard that consolidates all homelab services into a single tabbed interface with integrated homepage widgets showing real-time statistics from Jellyfin streams, Netdata metrics, and download client activity. It provides customizable authentication per-tab with support for SSO integration, user management with group-based access control, and a mobile-responsive interface for managing the entire infrastructure from anywhere. The service acts as a central hub replacing the need for multiple bookmarks or remembering service ports, offering both quick-access tabs and homepage cards with live data feeds from connected services. - -| Property | Value | -|----------|-------| -| **Image** | `organizr/organizr:latest` | -| **Container Name** | `organizr` | -| **Access URL (LAN)** | http://192.168.86.149:9999 | -| **Access URL (Public)** | https://home.schweitz.net | -| **External Access** | Yes (via NPM reverse proxy with SSL) | -| **Port Mapping** | 9999:80 (HTTP), 443:443 (HTTPS) | -| **Network Mode** | Bridge | -| **Restart Policy** | `unless-stopped` | -| **Volume Mounts** | `~/docker-data/organizr:/config` | -| **Environment** | `DB_TYPE=pgsql`, `DB_HOST=postgres-shared`, `DB_PORT=5432`, `DB_NAME=organizr`, `DB_USER=organizr_user`, `DB_PASS=${ORGANIZR_DB_PASSWORD}` | -| **Resource Limits** | None | -| **GPU Required** | No | -| **Dependencies** | PostgreSQL Shared | -| **Database** | PostgreSQL on `postgres-shared` (database `organizr`) | -| **Database Size** | ~5-10MB (typical) | -| **Integrated Services** | Jellyfin, Netdata | -| **Authentication** | Internal (supports SSO, Plex OAuth, LDAP) | - -**Configuration**: - -1. **In Portainer, navigate to the `organizr` stack.** -2. **Go to the "Env" tab and ensure the following environment variables are set:** - * `DB_TYPE=pgsql` - * `DB_HOST=postgres-shared` - * `DB_PORT=5432` - * `DB_NAME=organizr` - * `DB_USER=organizr_user` - * `DB_PASS`: This should be a secret. Create a secret in Portainer named `ORGANIZR_DB_PASSWORD` and set its value to the password you generated for the `organizr_user`. -3. **Redeploy the `organizr` stack.** - ---- +## Dashboard Layer ### Tatlock UI -Tatlock UI is a modern Flutter-based home lab dashboard designed to replace Organizr, providing a responsive web interface for monitoring and accessing all infrastructure services. Built as a stateless static web application served via nginx, it offers fast load times and a clean, customizable interface for the tower-of-joy infrastructure. The Flutter web build is compiled and containerized via Gitea Actions, with automatic deployment through Watchtower. +Tatlock UI is a modern Flutter-based home lab dashboard providing a responsive web interface for monitoring and accessing all infrastructure services. Built as a stateless static web application served via nginx, it offers fast load times and a clean, customizable interface for the tower-of-joy infrastructure. The Flutter web build is compiled and containerized via Gitea Actions, with automatic deployment through Watchtower. | Property | Value | |----------|-------| | **Image** | `git.schweitz.net/jpmschweitzer/tatlock-ui:latest` | | **Container Name** | `tatlock-ui` | -| **Access URL (LAN)** | http://192.168.86.149:8092 | -| **Access URL (Public)** | https://home.schweitz.net (future, replacing Organizr) | -| **External Access** | LAN only (future: via NPM reverse proxy with SSL) | -| **Port Mapping** | 8092:80 (HTTP) | +| **Access URL (LAN)** | http://192.168.86.149:9999 | +| **Access URL (Public)** | https://home.schweitz.net | +| **External Access** | Yes (via NPM reverse proxy with SSL) | +| **Port Mapping** | 9999:80 (HTTP) | | **Network Mode** | Bridge (docker-dataplane) | | **Restart Policy** | `unless-stopped` | | **Volume Mounts** | None (stateless static web app) | @@ -675,8 +604,6 @@ Gitea is a lightweight, self-hosted Git service providing repository hosting, is | **Code-Server** | https://code.schweitz.net | Yes | Browser-based IDE | | **Ollama** | http://192.168.86.149:11434 | No | ML model API | | **Headscale** | http://192.168.86.149:8085 | No | VPN control server | -| **Netdata** | http://192.168.86.149:19999 | No | System metrics | -| **Organizr** | https://home.schweitz.net | Yes | Unified dashboard | | **Open WebUI** | https://webui.schweitz.net | Yes (SSO) | LLM chat interface | | **Tatlock** | https://tatlock.schweitz.net | Yes (SSO) | AI orchestration API | | **Core API** | http://192.168.86.149:8083 | No | API functions & infrastructure mgmt | @@ -685,7 +612,7 @@ Gitea is a lightweight, self-hosted Git service providing repository hosting, is | **Gitea** | https://git.schweitz.net | Yes | Git repository hosting | | **Samba** | \\\\192.168.86.149 | No | Network file shares | | **Home Assistant** | https://housekeeping.schweitz.net | Yes | Smart home automation | -| **Tatlock UI** | http://192.168.86.149:8092 | No (future: Yes) | Home lab dashboard | +| **Tatlock UI** | https://home.schweitz.net | Yes | Home lab dashboard | | **Watchtower** | N/A (background) | N/A | Auto-updates | --- @@ -712,8 +639,6 @@ Gitea is a lightweight, self-hosted Git service providing repository hosting, is | **Code-Server** | `~/.config/code-server/`, `~/docker-data/code-server/` | N/A | Config: ~5MB, Extensions: ~50-200MB, User data: ~50MB | | **Ollama** | `~/docker-data/ollama/models/` | Alt: `/mnt/media/ollama/` | 2-15GB per model | | **Headscale** | `~/docker-data/headscale/` | N/A | ~10MB | -| **Netdata** | RAM-based (ephemeral) | N/A | ~200MB RAM | -| **Organizr** | `~/docker-data/organizr/` | N/A | ~50MB | | **Open WebUI** | `~/docker-data/open-webui/` | N/A | ~100MB | | **Core API** | `~/docker-data/core-api/` | N/A | Logs: ~10MB | | **Jellyfin** | `~/docker-data/jellyfin/` | `/mnt/media/jellyfin/` | Config: ~500MB, Media: ~2TB | @@ -734,7 +659,7 @@ Gitea is a lightweight, self-hosted Git service providing repository hosting, is | Network Name | Containers | Purpose | |--------------|------------|---------| -| **docker-dataplane** | Ollama, Open WebUI, Core API, Qdrant, PostgreSQL Shared, Redis Shared, Headscale, Nextcloud, Gitea, Samba, Watchtower, Organizr, Netdata, Home Assistant | Unified service mesh for all containerized applications | +| **docker-dataplane** | Ollama, Open WebUI, Core API, Qdrant, PostgreSQL Shared, Redis Shared, Headscale, Nextcloud, Gitea, Samba, Watchtower, Tatlock UI, Home Assistant | Unified service mesh for all containerized applications | | **host** | Portainer, NPM | Direct host port access for infrastructure management | **Benefits of Consolidation**: diff --git a/Makefile b/Makefile index de55ed0..495e86a 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ help: @echo "" @echo "Available Stacks:" @echo " - portainer, nginx-proxy-manager, ollama" - @echo " - headscale, netdata" + @echo " - headscale" @echo " - watchtower, maintenance" @echo " - jellyfin, nextcloud, samba" @echo "" @@ -109,7 +109,7 @@ update-%: # Setup directories setup-dirs: @echo "Creating directory structure..." - @mkdir -p ~/docker-data/{portainer,nginx-proxy-manager,ollama,headscale,netdata,jellyfin,nextcloud,samba} + @mkdir -p ~/docker-data/{portainer,nginx-proxy-manager,ollama,headscale,jellyfin,nextcloud,samba} @mkdir -p /mnt/media/{jellyfin,nextcloud,game-servers,backups,downloads} @echo "✅ Directories created" @echo "" @@ -164,21 +164,9 @@ deploy-phase2: @echo " 2. Create user: docker exec headscale headscale users create homelab" @echo " 3. Generate key: docker exec headscale headscale preauthkeys create --user homelab" -# Quick deploy - Phase 3 monitoring +# Quick deploy - Phase 3 optimization deploy-phase3: - @echo "=== Deploying Phase 3: Monitoring ===" - @echo "" - @echo "Deploying Netdata..." - @make deploy-netdata - @echo "" - @echo "=== Phase 3 Complete ===" - @echo "" - @echo "Access monitoring:" - @echo " Netdata: http://localhost:19999" - -# Quick deploy - Phase 4 optimization -deploy-phase4: - @echo "=== Deploying Phase 4: Optimization ===" + @echo "=== Deploying Phase 3: Optimization ===" @echo "" @echo "[1/2] Deploying Watchtower..." @make deploy-watchtower diff --git a/README.md b/README.md index 31d3fab..12d1394 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > Self-hosted home server infrastructure with GPU-accelerated ML, media streaming, and secure remote access -**Main Dashboard:** https://home.schweitz.net (Organizr) +**Main Dashboard:** https://home.schweitz.net (Tatlock UI) ## Quick Links @@ -34,9 +34,8 @@ │ ├── docker-dataplane - Service mesh │ │ └── Headscale (8085) - VPN mesh │ ├─────────────────────────────────────────┤ -│ Monitoring Layer │ -│ ├── Netdata (19999) - Metrics │ -│ └── Organizr (8084) - Dashboard │ +│ Dashboard Layer │ +│ └── Tatlock UI (9999) - Dashboard │ ├─────────────────────────────────────────┤ │ Optimization Layer │ │ ├── Watchtower - Auto-updates │ @@ -69,7 +68,6 @@ portainer-core/ ├── services/ # Service source code │ ├── core-api/ # Infrastructure management API │ └── ... -├── organizr-widgets/ # Dashboard widgets ├── AGENTS.md # AI agent guidelines (single source of truth) ├── README.md # This file (documentation index) ├── PLANS.md # Implementation plan tracker @@ -130,7 +128,7 @@ See [External Services](docs/EXTERNAL_SERVICES.md) for services maintained in se | **Open WebUI** | 8081 | LLM chat interface | | **Nextcloud** | 8082 | Cloud storage | | **Core API** | 8083 | Infrastructure management API | -| **Organizr** | 8084 | Unified dashboard | +| **Tatlock UI** | 9999 | Home lab dashboard | | **Headscale** | 8085 | VPN control server | | **Jellyfin** | 8096 | Media streaming | | **Gitea** | 3002 | Git repository hosting | @@ -139,8 +137,6 @@ See [External Services](docs/EXTERNAL_SERVICES.md) for services maintained in se | **Redis Shared** | 6379 | Shared cache (internal) | | **Qdrant** | 6333, 6334 | Vector database | | **Ollama** | 11434 | ML model API | -| **Netdata** | 19999 | System monitoring | - See [Stacks Reference](docs/reference/stacks.md#port-allocation) for complete port allocation. ## GPU Services diff --git a/npm-configs/README.md b/npm-configs/README.md index 4a5de58..0ef9e96 100644 --- a/npm-configs/README.md +++ b/npm-configs/README.md @@ -2,35 +2,14 @@ This directory contains Nginx configuration snippets for Nginx Proxy Manager (NPM) forward authentication with Authentik. -## Files - -### `organizr-forward-auth.conf` -**Status:** 🧪 Testing -**Service:** Organizr (home.schweitz.net) -**Purpose:** First test deployment of forward auth to validate standalone outpost functionality - -**DO NOT APPLY TO OTHER SERVICES YET** - This is a proof-of-concept deployment to verify: -- Standalone outpost works correctly -- No redirect loops occur -- SSO functions as expected -- Cookie domain settings are correct - -Once proven stable, this configuration can be adapted for other services. - ## Deployment Strategy -### Phase 1: Single Service Test (Current) -- ✅ Deploy to Organizr only -- ✅ Test all authentication flows -- ✅ Verify no issues for 24-48 hours - -### Phase 2: Gradual Rollout (After Phase 1 Success) -Services to protect (in order): +Services to protect with forward auth (in order): 1. Core API (api.schweitz.net) - Use OIDC instead of forward auth 2. Nextcloud (cloud.schweitz.net) 3. Gitea (git.schweitz.net) 4. Jellyfin (media.schweitz.net) -5. Open WebUI, Netdata, etc. +5. Open WebUI, etc. **Rule:** Deploy to ONE service at a time, test for 24 hours before proceeding to next. diff --git a/npm-configs/organizr-forward-auth.conf b/npm-configs/organizr-forward-auth.conf deleted file mode 100644 index 3fea86c..0000000 --- a/npm-configs/organizr-forward-auth.conf +++ /dev/null @@ -1,133 +0,0 @@ -# NPM Forward Auth Configuration for Organizr (home.schweitz.net) -# Test deployment - single service only -# Date: 2025-11-21 -# Authentik Version: 2024.8.4 -# Standalone Outpost: authentik-proxy (port 9445) - -# =================================================================== -# IMPORTANT: Apply this ONLY to home.schweitz.net proxy host -# DO NOT apply to other services until this is proven stable -# =================================================================== - -# Increase buffer size for large headers from Authentik -proxy_buffers 8 16k; -proxy_buffer_size 32k; - -# Forward authentication via standalone outpost -auth_request /outpost.goauthentik.io/auth/nginx; -error_page 401 = @goauthentik_proxy_signin; - -# Capture auth response headers -auth_request_set $auth_cookie $upstream_http_set_cookie; -auth_request_set $authentik_username $upstream_http_x_authentik_username; -auth_request_set $authentik_groups $upstream_http_x_authentik_groups; -auth_request_set $authentik_email $upstream_http_x_authentik_email; -auth_request_set $authentik_name $upstream_http_x_authentik_name; -auth_request_set $authentik_uid $upstream_http_x_authentik_uid; - -# Forward auth headers to application -add_header Set-Cookie $auth_cookie; -proxy_set_header X-authentik-username $authentik_username; -proxy_set_header X-authentik-groups $authentik_groups; -proxy_set_header X-authentik-email $authentik_email; -proxy_set_header X-authentik-name $authentik_name; -proxy_set_header X-authentik-uid $authentik_uid; - -# Outpost proxy location -location /outpost.goauthentik.io { - proxy_pass https://localhost:9445/outpost.goauthentik.io; - proxy_set_header Host $host; - proxy_set_header X-Original-URL $scheme://$http_host$request_uri; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Host $http_host; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_pass_request_body off; - proxy_set_header Content-Length ""; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; -} - -# Signin redirect handler -location @goauthentik_proxy_signin { - internal; - return 302 https://auth.schweitz.net/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri; -} - -# =================================================================== -# DEPLOYMENT INSTRUCTIONS: -# =================================================================== -# -# 1. Open NPM UI: http://192.168.86.149:8000 -# 2. Navigate to: Hosts → Proxy Hosts -# 3. Find "home.schweitz.net" and click Edit -# 4. Go to the "Advanced" tab -# 5. PASTE THIS ENTIRE CONFIGURATION (lines 11-56) into the text box -# 6. Go to the "SSL" tab -# 7. Ensure "WebSockets Support" is ENABLED -# 8. Click "Save" -# -# =================================================================== -# TESTING PROCEDURE: -# =================================================================== -# -# Step 1: Test in Incognito Window -# - Open incognito/private browsing window -# - Navigate to: https://home.schweitz.net -# - Expected: Redirect to https://auth.schweitz.net -# - Login with Google OAuth -# - Expected: Redirect back to https://home.schweitz.net -# - Expected: Organizr loads successfully -# -# Step 2: Verify SSO Persistence -# - Close incognito window -# - Open new incognito window -# - Navigate to: https://home.schweitz.net -# - Expected: Still logged in (cookie persists) -# -# Step 3: Check Logs for Errors -# docker logs authentik-proxy 2>&1 | tail -50 -# - Look for any errors or warnings -# - Should see successful auth requests -# -# Step 4: Test Logout -# - Navigate to: https://auth.schweitz.net/if/flow/default-invalidation-flow/ -# - Should log out -# - Try accessing https://home.schweitz.net again -# - Expected: Redirect to login page -# -# =================================================================== -# ROLLBACK PROCEDURE (if issues occur): -# =================================================================== -# -# 1. Open NPM UI -# 2. Edit home.schweitz.net proxy host -# 3. Go to "Advanced" tab -# 4. DELETE all the configuration -# 5. Save -# 6. Organizr will be accessible without authentication again -# -# =================================================================== -# TROUBLESHOOTING: -# =================================================================== -# -# Issue: Redirect loop -# - Check that auth.schweitz.net does NOT have forward auth enabled -# - Verify AUTHENTIK_COOKIE_DOMAIN=.schweitz.net in provider settings -# -# Issue: 502 Bad Gateway -# - Check authentik-proxy container is running: docker ps | grep authentik-proxy -# - Check NPM can reach authentik-proxy: docker exec npm ping authentik-proxy -# -# Issue: 500 Internal Server Error -# - Check authentik-proxy logs: docker logs authentik-proxy -# - Verify Redis connection is working -# - Restart authentik-proxy: docker restart authentik-proxy -# -# Issue: Authentication works but Organizr doesn't load -# - Check buffer sizes are set correctly (lines 13-14) -# - Check WebSocket support is enabled in NPM SSL tab -# -# =================================================================== diff --git a/organizr-widgets/README.md b/organizr-widgets/README.md deleted file mode 100644 index c20995f..0000000 --- a/organizr-widgets/README.md +++ /dev/null @@ -1,224 +0,0 @@ -# Organizr Service Control Widget - -A beautiful, responsive widget for managing on-demand services from your Organizr dashboard. - -## Features - -- ✨ **Real-time Status** - Live service status with container counts -- 🎮 **One-Click Control** - Start/Stop services with a single click -- 🔒 **Safety First** - Always-on services are protected and clearly marked -- 🎨 **Beautiful UI** - Dark theme that matches Organizr -- ⚡ **Auto-Refresh** - Updates every 10 seconds -- 📱 **Responsive** - Works on desktop, tablet, and mobile - -## Screenshots - -### Service Cards -Each service shows: -- Service name -- Running status (Running/Stopped with container counts) -- Start/Stop buttons (disabled when not applicable) -- "ALWAYS ON" badge for infrastructure services - -## Installation - -### Method 1: Organizr Custom Homepage Item (Recommended) - -1. **Copy the widget file** to a web-accessible location: - ```bash - # If you have a web server serving files from /var/www/html: - sudo cp service-control.html /var/www/html/widgets/ - - # Or use Organizr's public directory: - cp service-control.html /path/to/organizr/plugins/widgets/ - ``` - -2. **Add to Organizr Homepage**: - - Open Organizr - - Go to **Settings** → **Customize** → **Homepage Items** - - Click **Add New Item** - - Configure: - - **Name**: "Service Control" - - **Category**: Custom - - **Type**: iFrame - - **URL**: `http://localhost/widgets/service-control.html` (adjust path) - - **Minimum Authentication**: User - - **Enabled**: Yes - - Save - -3. **Add to Homepage**: - - Go to **Settings** → **Customize** → **Appearance** - - Edit your homepage layout - - Add the "Service Control" item to desired location - - Save - -### Method 2: Organizr Custom HTML Tab - -1. **Open Organizr Settings**: - - Settings → **Tab Editor** - -2. **Add New Tab**: - - Click **Add Tab** - - Configure: - - **Tab Name**: "Services" - - **Tab URL**: Leave empty - - **Category**: Custom - - **Type**: iFrame - - **Image**: `images/tabs/services.png` (or your choice) - -3. **Add Custom HTML**: - - In the same tab configuration, find **Custom HTML** section - - Copy and paste the entire contents of `service-control.html` - - Save - -4. **Access the Tab**: - - The "Services" tab will now appear in your Organizr sidebar - -### Method 3: Nginx Reverse Proxy Integration - -If you want to serve the widget through Nginx Proxy Manager: - -1. **Create a location** in your Organizr proxy host: - ```nginx - location /widgets/ { - alias /path/to/portainer-core/organizr-widgets/; - autoindex off; - } - ``` - -2. **Access via**: `https://your-organizr-domain.com/widgets/service-control.html` - -## Configuration - -### Changing API Endpoint - -If your core-api is not on `localhost:8083`, edit the widget file: - -```javascript -const API_BASE = 'http://your-server:8083'; // Change this line -``` - -### Adjusting Auto-Refresh Interval - -Default is 10 seconds. To change: - -```javascript -setInterval(fetchServices, 10000); // Change 10000 to desired milliseconds -``` - -### Customizing Displayed Services - -By default, the widget shows all stoppable services (excludes always-on infrastructure). - -To filter specific services, modify the `renderServices()` function: - -```javascript -const stoppableServices = services.filter(s => - !isAlwaysOn(s.name) && - ['jellyfin', 'nextcloud', 'gitea', 'ai-stack'].includes(s.name) // Add this line -); -``` - -## Troubleshooting - -### "Failed to connect to API" - -**Problem**: Widget shows red error message - -**Solutions**: -1. Verify core-api is running: `docker ps | grep core-api` -2. Check core-api URL is correct (localhost vs IP address) -3. If accessing from remote, change `API_BASE` to full URL -4. Check browser console for CORS errors - -### CORS Issues - -If accessing widget from a different domain than core-api: - -**Option 1**: Update core-api CORS settings in `src/config.py`: -```python -cors_origins: list[str] = ["http://your-organizr-domain.com"] -``` - -**Option 2**: Proxy the API through same domain using Nginx - -### Services Not Appearing - -**Check**: -1. Services are deployed as Portainer stacks -2. Services have proper labels: `com.docker.compose.project` -3. Core-API can connect to Portainer -4. Check browser console for errors - -### Buttons Disabled - -**Expected Behavior**: -- Start button disabled when service is running -- Stop button disabled when service is stopped -- All buttons disabled for always-on services - -## Service Groups - -The following service groups are defined (stopping one stops all in group): - -- **jellyfin**: jellyfin -- **nextcloud**: nextcloud (uses shared postgres-shared + redis-shared) -- **gitea**: gitea, gitea-db -- **ai-stack**: open-webui, ollama, qdrant -- **samba**: samba - -## Always-On Services (Cannot be stopped) - -These infrastructure services are protected: -- portainer -- nginx-proxy-manager -- core-api -- organizr -- headscale -- watchtower -- netdata -- maintenance -- postgres-shared (shared database infrastructure) -- redis-shared (shared cache infrastructure) - -## Advanced: Customizing the UI - -### Colors - -Edit the CSS variables in the ` - -
-