--- title: Pocket Clips description: Integrating Stash published: true date: 2026-02-22T05:20:31.865Z tags: editor: markdown dateCreated: 2026-02-20T04:48:11.191Z --- # Pocket Grimoire - Stash Integration Guide **Adding Stash media library manager to Pocket Grimoire using two-instance architecture with ZFS replication** --- ## Overview This guide extends the Pocket Grimoire deployment to include Stash using a **two-instance architecture**: - **Stash-Main** on Netgrimoire watches your entire media library - **Stash-Pocket** on Netgrimoire watches only curated personal content (GREEN drive) - **Stash-Pocket** replicates to Pocket Grimoire's GREEN drive for offline access This approach provides: - Full library management at home (Stash-Main) - Curated personal subset with independent database (Stash-Pocket) - Automatic synchronization via existing ZFS replication to GREEN drive - Read-only browsing on travel with all previews pre-generated - Zero CPU load on travel Pi (no scanning/generation) **Key Principle:** All intensive operations happen on Netgrimoire. Pocket Grimoire just serves pre-generated content in read-only mode. **Important:** Stash data lives on the GREEN drive (personal media), NOT on VAULT. VAULT is for backups only. --- ## Architecture ``` ┌─────────────────────────────────────────────────────┐ │ NETGRIMOIRE (Home) │ ├─────────────────────────────────────────────────────┤ │ │ │ Stash Instance #1: "Stash-Main" (Port 9999) │ │ ├─ Watches: ALL media libraries │ │ ├─ Config: /export/vault/stash-main/config │ │ ├─ Generated: /export/vault/stash-main/generated │ │ ├─ Blobs: /export/vault/stash-main/blobs │ │ ├─ Database: 1-5GB (full library) │ │ └─ Does NOT sync to Pocket │ │ │ │ Stash Instance #2: "Stash-Pocket" (Port 9998) │ │ ├─ Watches: ONLY Green/Pocket (personal content) │ │ ├─ Location: /export/Green/Pocket/ │ │ │ ├── media/library/ (personal media) │ │ │ └── stash/ (Stash-Pocket data) │ │ │ ├── config/ (database) │ │ │ ├── generated/ (previews) │ │ │ └── blobs/ (markers) │ │ ├─ Database: 200MB-1GB (personal subset) │ │ └─ SYNCS to Pocket GREEN drive via ZFS │ │ │ └─────────────────────────────────────────────────────┘ ↓ ZFS Send (syncoid) (vault/Green/Pocket → greenpg/Pocket) ↓ ┌─────────────────────────────────────────────────────┐ │ POCKET GRIMOIRE (Travel) │ ├─────────────────────────────────────────────────────┤ │ │ │ GREEN Drive (greenpg pool): │ │ └─ /srv/greenpg/Pocket/ (dataset from sync) │ │ ├─ media/library/ (media files) │ │ └─ stash/ (Stash data) │ │ │ │ Stash Instance: "Stash-Pocket" (Port 9999) │ │ ├─ Watches: GREEN media only (read-only) │ │ ├─ Location: /srv/greenpg/Pocket/ │ │ │ ├── media/library/ (synced media) │ │ │ └── stash/ (synced, read-only) │ │ │ ├── config/ (synced database) │ │ │ ├── generated/ (synced previews) │ │ │ └── blobs/ (synced markers) │ │ ├─ Same database as Netgrimoire Stash-Pocket │ │ └─ Browse only - no scanning or generation │ │ │ └─────────────────────────────────────────────────────┘ ``` --- ## Why Two Instances? ### Benefits of Two-Instance Architecture ✅ **Stash-Main (Port 9999):** - Manages your entire home media library - Heavy operations (scanning, tagging, preview generation) - Full featured - edit, organize, tag anything - Stays on Netgrimoire (doesn't sync to Pocket) ✅ **Stash-Pocket (Port 9998 at home, 9999 on travel):** - Manages only curated personal content (GREEN drive) - Smaller database (faster, lighter) - Independent from main library - Syncs to Pocket Grimoire's GREEN drive automatically - Preview personal setup before trips ✅ **Separation of Concerns:** - Main library can be massive (thousands of videos) - Personal subset is manageable (hundreds of videos) - No confusion about what's available where - Changes to main library don't affect travel copy - Faster sync times (only GREEN data replicates) --- ## Storage Requirements ### On Netgrimoire **Stash-Main (Does NOT sync):** ``` Location: /export/vault/stash-main/ Database: 1-5GB (depends on library size) Generated previews: 50-200GB (depends on settings) Blobs/markers: 5-20GB ───────────────────────────────────────────── Total: ~56-225GB (stays on Netgrimoire) ``` **Stash-Pocket (DOES sync to GREEN drive):** ``` Location: /export/Green/Pocket/stash/ Database: 200MB-1GB (smaller subset) Generated previews: 5-20GB Blobs/markers: 1-5GB ───────────────────────────────────────────── Total: ~6-26GB (syncs to Pocket GREEN) ``` **Personal Media (syncs to GREEN drive):** ``` Location: /export/Green/Pocket/media/ Content: 500GB-1TB (curated for travel) ───────────────────────────────────────────── Total Green/Pocket: ~506GB-1TB (vault/Green/Pocket dataset) ``` ### On Pocket Grimoire (GREEN Drive) ``` Location: /srv/greenpg/Pocket/ Stash data: ~6-26GB (synced from Netgrimoire) Media files: ~500GB-1TB (synced from Netgrimoire) ───────────────────────────────────────────── Total: ~506GB-1TB on GREEN SSD This fits comfortably on a 2TB+ GREEN SSD. ``` **Note:** VAULT drive contains backups only (no Stash, no media). --- ## Resource Impact ### Updated Resource Profile (With Stash) **Netgrimoire (Running Two Instances):** Idle: ``` Stash-Main: ~400MB RAM Stash-Pocket: ~300MB RAM (smaller database) ──────────────────────────── Total: ~700MB RAM CPU: <5% ``` During operations: ``` Stash-Main (scanning): ~1-2GB RAM, 80%+ CPU Stash-Pocket (scanning): ~500MB RAM, 40% CPU Note: Run intensive tasks one at a time ``` **Pocket Grimoire (Single Instance, Read-Only):** Idle: ``` Wiki.js + PostgreSQL: ~250MB RAM Jellyfin (idle): ~150MB RAM Stash-Pocket: ~200MB RAM ZFS ARC: ~512MB RAM System: ~200MB RAM ───────────────────────────────── Total: ~1.3GB / 8GB RAM ✓ CPU: <10% Temperature: Cool ``` Browsing Stash: ``` Stash-Pocket (active): ~300MB RAM Other services: ~1.1GB RAM ───────────────────────────────── Total: ~1.4GB / 8GB RAM ✓ CPU: <15% Temperature: Cool to Warm ``` Media playback + Stash: ``` Jellyfin (serving): ~200MB RAM Stash (browsing): ~300MB RAM Wiki.js + PostgreSQL: ~250MB RAM ZFS ARC: ~512MB RAM System: ~200MB RAM ───────────────────────────────── Total: ~1.5GB / 8GB RAM ✓ Still plenty of headroom ``` --- ## Installation: Netgrimoire (Home) ### 1. Create Directory Structure ```bash # Create Stash-Main directories (NOT in Green folder - won't sync) sudo mkdir -p /export/vault/stash-main/{config,generated,blobs,cache} sudo chown -R 1000:1000 /export/vault/stash-main sudo chmod -R 755 /export/vault/stash-main # Stash-Pocket directories in existing Green/Pocket dataset # Your dataset: vault/Green/Pocket mounted at /export/Green/Pocket sudo mkdir -p /export/Green/Pocket/stash/{config,generated,blobs,cache} sudo mkdir -p /export/Green/Pocket/media/library/{movies,tv} sudo chown -R 1000:1000 /export/Green/Pocket sudo chmod -R 755 /export/Green/Pocket ``` **Verify structure:** ```bash tree -L 2 /export/vault/stash-main tree -L 3 /export/Green/Pocket # Should show: # /export/Green/Pocket/ # ├── stash/ # │ ├── config/ # │ ├── generated/ # │ ├── blobs/ # │ └── cache/ # └── media/ # └── library/ ``` ### 2. Curate Pocket Media Content **Copy or move curated travel content to Pocket location:** ```bash # Example: Copy favorite movies to Pocket cp /export/vault/media/library/movies/favorites/*.mp4 \ /export/vault/Green/Pocket/media/library/movies/ # Example: Copy specific TV show seasons cp -r /export/vault/media/library/tv/ShowName/Season01 \ /export/vault/Green/Pocket/media/library/tv/ # Or organize a dedicated travel collection mkdir -p /export/vault/Green/Pocket/media/library/travel-collection # ... add curated content ... ``` **Important:** This is your travel media library. Keep it manageable (500GB-1TB). ### 3. Stash-Main Docker Compose **Create directory:** ```bash mkdir -p /srv/netgrimoire/stacks/stash-main ``` **File:** `/srv/netgrimoire/stacks/stash-main/docker-compose.yml` ```yaml services: stash-main: image: stashapp/stash:latest container_name: netgrimoire_stash_main environment: - STASH_STASH=/data/ - STASH_GENERATED=/generated/ - STASH_CACHE=/cache/ - STASH_BLOBS=/blobs/ - TZ=America/Chicago volumes: # Stash-Main data (NOT in Pocket directory - won't sync) - /export/vault/stash-main/config:/root/.stash - /export/vault/stash-main/generated:/generated - /export/vault/stash-main/blobs:/blobs - /export/vault/stash-main/cache:/cache # Watch ALL media libraries - /export/vault/media:/data:ro # Optionally also include Pocket media in main view # - /export/vault/Green/Pocket/media:/data/pocket:ro ports: - "9999:9999" restart: unless-stopped ``` **Start Stash-Main:** ```bash cd /srv/netgrimoire/stacks/stash-main docker compose up -d # Check logs docker logs -f netgrimoire_stash_main # Access: http://netgrimoire.local:9999 ``` ### 4. Stash-Pocket Docker Compose **Create directory:** ```bash mkdir -p /srv/netgrimoire/stacks/stash-pocket ``` **File:** `/srv/netgrimoire/stacks/stash-pocket/docker-compose.yml` ```yaml services: stash-pocket: image: stashapp/stash:latest container_name: netgrimoire_stash_pocket environment: - STASH_STASH=/data/ - STASH_GENERATED=/generated/ - STASH_CACHE=/cache/ - STASH_BLOBS=/blobs/ - TZ=America/Chicago volumes: # Stash-Pocket data (IN Pocket directory - will sync) - /export/vault/Green/Pocket/stash/config:/root/.stash - /export/vault/Green/Pocket/stash/generated:/generated - /export/vault/Green/Pocket/stash/blobs:/blobs - /export/vault/Green/Pocket/stash/cache:/cache # Watch ONLY Pocket media - /export/vault/Green/Pocket/media:/data:ro ports: - "9998:9999" # Different external port to avoid conflict restart: unless-stopped ``` **Note:** Container uses port 9999 internally, but exposed as 9998 externally to avoid conflict with Stash-Main. **Start Stash-Pocket:** ```bash cd /srv/netgrimoire/stacks/stash-pocket docker compose up -d # Check logs docker logs -f netgrimoire_stash_pocket # Access: http://netgrimoire.local:9998 ``` **Verify both running:** ```bash docker ps | grep stash # Should show: # netgrimoire_stash_main (port 9999) # netgrimoire_stash_pocket (port 9998) ``` ### 5. Configure Stash-Main **Access:** `http://netgrimoire.local:9999` 1. **Initial Setup Wizard:** - Set admin password - Configure paths (default /data should work) - Complete setup 2. **Add Libraries:** - Settings → Library - Add folder: `/data/library` (or your structure) - Save 3. **Run Initial Scan:** - Tasks → Scan - Wait for completion (can take hours for large libraries) 4. **Configure Preview Generation:** - Settings → Tasks → Generate - Video encoding: VP9 or H.264 - Resolution: 720p (good quality, reasonable size) - Preview duration: 20-60 seconds - Enable image previews - Enable sprites 5. **Generate Previews:** - Tasks → Generate → Previews - This is CPU intensive - let run overnight - Can take many hours for large libraries 6. **Organize and Tag:** - Tag performers, studios, scenes - Create collections, galleries - Add markers, metadata - This is your full-featured home library ### 6. Configure Stash-Pocket **Access:** `http://netgrimoire.local:9998` 1. **Initial Setup Wizard:** - Set admin password (can be same as Stash-Main) - Configure paths (default /data should work) - Complete setup 2. **Add Library:** - Settings → Library - Add folder: `/data/library` - Save 3. **Run Initial Scan:** - Tasks → Scan - Should be much faster (smaller library) - Wait for completion 4. **Configure Preview Generation:** - Use same settings as Stash-Main - Settings → Tasks → Generate - Resolution: 720p - Preview duration: 20-60 seconds 5. **Generate Previews:** - Tasks → Generate → Previews - Much faster than Stash-Main (fewer videos) - Let complete before first trip 6. **Organize (Optional):** - Tag travel-specific content - Create "Travel Favorites" collections - Can copy/import tags from Stash-Main if desired - Or keep separate organization **Why configure Stash-Pocket separately?** - Independent database from Stash-Main - Travel-specific organization - Can have different preview settings (optimize for size) - Preview what will be available on travel ### 7. Verify Data in Pocket Directory ```bash # Check Stash-Pocket database exists ls -lh /export/vault/Green/Pocket/stash/config/ # Should show: stash-go.sqlite (database file) # Check previews generated ls -lh /export/vault/Green/Pocket/stash/generated/ # Should show: many .webp or .mp4 preview files # Check media is present ls -lh /export/vault/Green/Pocket/media/library/movies/ # Should show: your curated travel media ``` --- ## Installation: Pocket Grimoire (Travel) ### 1. Wait for Initial Sync **Your existing ZFS sync handles everything:** ```bash # This already exists in your sync script: syncoid --no-sync-snap --recursive \ --sshkey "${SSH_KEY}" \ "root@${NETGRIMOIRE}:vault/Green/Pocket" \ "vaultpg/Green/Pocket" ``` **This syncs:** - ✅ Stash-Pocket database - ✅ Stash-Pocket previews - ✅ Stash-Pocket blobs/markers - ✅ Pocket media files - ✅ Wiki, photos, documents (already syncing) **Initial sync time:** - Stash data: 10-30 minutes - Media files: 1-4 hours (depending on size) - Total: 1-5 hours for first sync **Check sync status:** ```bash # On Pocket Grimoire tail -f /var/log/pocketgrimoire-sync.log # Verify data arrived ls /srv/vaultpg/Green/Pocket/stash/ ls /srv/vaultpg/Green/Pocket/media/ ``` ### 2. Verify Synced Data ```bash # SSH into Pocket Grimoire ssh user@pocket-grimoire.local # Check Stash database ls -lh /srv/vaultpg/Green/Pocket/stash/config/ # Should show: stash-go.sqlite # Check previews ls /srv/vaultpg/Green/Pocket/stash/generated/ | wc -l # Should show: hundreds of preview files # Check media du -sh /srv/vaultpg/Green/Pocket/media/ # Should show: 500GB-1TB ``` ### 3. Create Stash Docker Compose **Create directory:** ```bash mkdir -p /srv/pocket-grimoire/stacks/stash mkdir -p /srv/pocket-grimoire/data/stash/cache ``` **File:** `/srv/pocket-grimoire/stacks/stash/docker-compose.yml` ```yaml services: stash: image: stashapp/stash:latest container_name: pocketgrimoire_stash environment: - STASH_STASH=/data/ - STASH_GENERATED=/generated/ - STASH_CACHE=/cache/ - STASH_BLOBS=/blobs/ - TZ=America/Chicago volumes: # Point to synced Pocket directory on GREEN drive (READ-ONLY) - /srv/greenpg/Pocket/stash/config:/root/.stash:ro - /srv/greenpg/Pocket/stash/generated:/generated:ro - /srv/greenpg/Pocket/stash/blobs:/blobs:ro # Local cache only (writable, not synced) - /srv/pocket-grimoire/data/stash/cache:/cache # Media location on GREEN drive (read-only) - /srv/greenpg/Pocket/media:/data:ro ports: - "9999:9999" # Standard port on Pocket (no conflict) restart: unless-stopped ``` **Note the `:ro` flags** - Everything except local cache is read-only. ### 4. Start Stash on Pocket Grimoire ```bash cd /srv/pocket-grimoire/stacks/stash docker compose up -d # Check logs docker logs -f pocketgrimoire_stash # Verify running docker ps | grep stash ``` ### 5. Access and Verify **Access:** `http://pocket-grimoire.local:9999` **Should see:** - Same library as Netgrimoire Stash-Pocket - All previews available - All scene markers working - All metadata present - Works fully offline **Verify read-only mode:** - Try to edit a scene → Should fail with permission error - Try to scan library → Should fail - Try to generate previews → Should fail - This confirms read-only mode is working ### 6. Disable Background Tasks **In Stash UI:** - Settings → Tasks - Disable all automatic tasks: - ❌ Auto-scan - ❌ Auto-tag - ❌ Auto-preview generation - ❌ Auto-cleanup - Save settings **Why?** Even though filesystem is read-only, these tasks will try to run and fail. Better to disable. --- ## ZFS Replication Configuration ### Your Existing Sync Script Already Works! **File:** `/usr/local/sbin/pocketgrimoire-zfs-pull.sh` **Current sync (should already include this):** ```bash #!/usr/bin/env bash set -euo pipefail SRC_HOST="netgrimoire.local" SSH_KEY="/srv/pocket-grimoire/keys/zfs_pull_ro" # Sync vault/Green/Pocket to GREEN drive (greenpg/Pocket) syncoid --no-sync-snap \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/Green/Pocket" \ "greenpg/Pocket" # This single command syncs: # - /export/Green/Pocket/stash/ → Stash-Pocket data # - /export/Green/Pocket/media/ → Media files # All Pocket data syncs to GREEN drive automatically ``` **No additional sync commands needed!** ✅ **Stash-Main data does NOT sync** (it's in `/export/vault/stash-main/`, outside Pocket directory). **Note:** The sync destination is `greenpg/Pocket` on the GREEN drive, NOT `vaultpg`. Stash and media data live on GREEN, not VAULT. ### Sync Frequency **Your existing timer:** Every 6 hours This is perfect for Stash: - Database changes sync regularly - New previews sync automatically - New media syncs when added **To sync immediately (before trips):** ```bash sudo systemctl start pocketgrimoire-sync.service tail -f /var/log/pocketgrimoire-sync.log ``` --- ## Workflow ### At Home: Adding Content for Travel **1. Curate new content:** ```bash # On Netgrimoire cp /export/vault/media/library/movies/new-favorites/*.mp4 \ /export/vault/Green/Pocket/media/library/movies/ ``` **2. Scan Stash-Pocket:** ``` Open: http://netgrimoire.local:9998 Tasks → Scan Wait for completion ``` **3. Generate previews (if needed):** ``` Tasks → Generate → Previews Wait for completion ``` **4. Let sync happen (automatic):** - Next 6-hour sync cycle picks up changes - Or trigger manually: `sudo systemctl start pocketgrimoire-sync.service` **5. Verify on Pocket Grimoire:** ``` Open: http://pocket-grimoire.local:9999 Should show new content after sync ``` ### At Home: Previewing Travel Setup **Access Stash-Pocket on Netgrimoire:** ``` http://netgrimoire.local:9998 ``` **This shows exactly what will be available on Pocket Grimoire:** - Same library - Same previews - Same organization - Test before traveling ### While Traveling: Browsing Content **On Pocket Grimoire:** ``` http://pocket-grimoire.local:9999 ``` **Features available offline:** - ✅ Browse entire Pocket library - ✅ View all previews - ✅ See scene markers - ✅ Search and filter - ✅ View performer/studio info - ❌ Cannot edit or tag (read-only) - ❌ Cannot scan or generate (read-only) **Play media:** - Click video in Stash - Opens in browser player - Or copy path and open in Jellyfin - Or use StashApp on Onn boxes ### If You Need to Edit While Traveling **VPN back to Netgrimoire:** 1. Connect Beryl AX to hotel WiFi 2. WireGuard VPN connects to Netgrimoire 3. Access Netgrimoire Stash-Pocket: `http://netgrimoire.local:9998` 4. Make edits there 5. Changes sync on next cycle --- ## Accessing Stash ### From Web Browser **At Home (Netgrimoire):** ``` Stash-Main (Full Library): http://netgrimoire.local:9999 Stash-Pocket (Travel Subset): http://netgrimoire.local:9998 ``` **While Traveling (Pocket Grimoire):** ``` Stash-Pocket (Travel Subset): http://pocket-grimoire.local:9999 ``` **From Laptop (via browser):** - Connect to portapotty WiFi - Open browser to above URLs - Works same as Netgrimoire ### From Onn Streaming Boxes **Install StashApp for Android TV:** - See "Onn 4K Streaming Box Setup Guide" for detailed instructions - Download APK: https://github.com/damontecres/StashAppAndroidTV/releases - Sideload onto Onn boxes **Configure StashApp:** ``` Server URL: http://pocket-grimoire.local:9999 Or: http://10.0.0.10:9999 (if .local doesn't resolve) API Key: (if required - found in Stash settings) ``` **Features on Onn:** - Browse Stash library - View previews and scene markers - Play videos directly - Search and filter - Full touch/remote control ### From Phone/Tablet **Via Web Browser:** ``` Connect to portapotty WiFi Open: http://pocket-grimoire.local:9999 Mobile-responsive interface works well ``` --- ## Service Access Summary **Updated with Stash:** ``` When connected to portapotty network: Wiki.js: http://pocket-grimoire.local:3000 Jellyfin: http://pocket-grimoire.local:8096 Stash: http://pocket-grimoire.local:9999 ← NEW File Browser: http://pocket-grimoire.local:8080 Dozzle: http://pocket-grimoire.local:8888 SSH: ssh user@pocket-grimoire.local NFS Media: nfs://pocket-grimoire.local/srv/mediapg Router Admin: http://192.168.8.1 At Home (Netgrimoire): Stash-Main: http://netgrimoire.local:9999 Stash-Pocket: http://netgrimoire.local:9998 ``` --- ## Troubleshooting ### Stash Won't Start on Pocket Grimoire **Check Docker container status:** ```bash docker ps | grep stash docker logs pocketgrimoire_stash ``` **Common issues:** - **ZFS datasets not mounted:** ```bash zfs list | grep Pocket sudo zfs mount -a ``` - **Permissions denied:** ```bash ls -ld /srv/vaultpg/Green/Pocket/stash/ # Should show ownership 1000:1000 sudo chown -R 1000:1000 /srv/vaultpg/Green/Pocket/stash/ ``` - **Port conflict:** ```bash sudo netstat -tlnp | grep 9999 # If another service is using port 9999, change in docker-compose.yml ``` ### Stash Shows "Database is locked" **This is expected - read-only mode is working correctly.** The database file is mounted read-only (`:ro` flag), so Stash cannot write to it. **If you need to make changes:** 1. VPN to Netgrimoire 2. Access: `http://netgrimoire.local:9998` 3. Edit on Netgrimoire Stash-Pocket 4. Changes sync on next cycle ### Previews Not Showing on Pocket Grimoire **Verify previews synced:** ```bash ls /srv/vaultpg/Green/Pocket/stash/generated/ # Should show many .webp or .mp4 files du -sh /srv/vaultpg/Green/Pocket/stash/generated/ # Should show several GB ``` **If empty:** - Previews not generated on Netgrimoire yet - Generate: `http://netgrimoire.local:9998` → Tasks → Generate - Sync hasn't completed - Check: `tail -f /var/log/pocketgrimoire-sync.log` - Sync failed - Check logs for errors - Manually trigger: `sudo systemctl start pocketgrimoire-sync.service` ### Media Files Not Found **Check media synced:** ```bash ls /srv/vaultpg/Green/Pocket/media/library/movies/ # Should show video files du -sh /srv/vaultpg/Green/Pocket/media/ # Should show 500GB-1TB ``` **If empty:** - Media not in Pocket directory on Netgrimoire - Check: `/export/vault/Green/Pocket/media/` - Sync hasn't completed (media takes longest) - Wait or trigger manual sync - Check progress: `zfs list vaultpg/Green/Pocket` **Verify Docker volume mount:** ```bash docker inspect pocketgrimoire_stash | grep -A 10 Mounts # Should show /srv/vaultpg/Green/Pocket/media mounted as /data ``` ### Sync Takes Too Long **Check what's being synced:** ```bash # Watch sync progress tail -f /var/log/pocketgrimoire-sync.log # Check dataset sizes zfs list | grep Pocket ``` **Optimization tips:** 1. **Reduce preview quality on Netgrimoire:** - Stash-Pocket settings: Lower resolution (480p instead of 720p) - Smaller files = faster sync 2. **Sync less frequently:** - Change timer from 6h to 12h or 24h - Edit: `/etc/systemd/system/pocketgrimoire-sync.timer` 3. **Compress during sync:** ```bash syncoid --compress=lz4 \ "root@${SRC_HOST}:vault/Green/Pocket" \ "vaultpg/Green/Pocket" ``` 4. **Bandwidth limit (if needed):** ```bash syncoid --bwlimit=50M \ "root@${SRC_HOST}:vault/Green/Pocket" \ "vaultpg/Green/Pocket" ``` ### Stash API Key Issues (StashApp) **If StashApp asks for API key:** **On Netgrimoire Stash-Pocket:** ``` http://netgrimoire.local:9998 Settings → Security → API Key Generate key if not present Copy key ``` **API key is in config file (synced to Pocket):** ```bash # On Netgrimoire cat /export/vault/Green/Pocket/stash/config/config.yml | grep api_key # On Pocket (after sync) cat /srv/vaultpg/Green/Pocket/stash/config/config.yml | grep api_key ``` **Configure StashApp:** - Settings → Server → API Key - Paste key - Connect **Note:** API key syncs with config, so should be same on both systems. ### Two Instances Conflict on Netgrimoire **Problem:** Both Stash instances try to use same port **Solution:** Already handled - different external ports - Stash-Main: External 9999 → Internal 9999 - Stash-Pocket: External 9998 → Internal 9999 **Verify no conflict:** ```bash sudo netstat -tlnp | grep 9999 # Should show: netgrimoire_stash_main sudo netstat -tlnp | grep 9998 # Should show: netgrimoire_stash_pocket ``` --- ## Optimization Tips ### Reduce Storage Usage **On Netgrimoire (affects Pocket via sync):** 1. **Lower preview quality for Stash-Pocket:** ``` http://netgrimoire.local:9998 Settings → Tasks → Generate - Video resolution: 480p (instead of 720p) - Lower bitrate - Shorter duration (20s instead of 60s) ``` 2. **Disable sprite generation:** ``` Settings → Tasks → Generate - Disable sprite generation - Just use video previews - Saves significant space ``` 3. **Selective preview generation:** ``` Don't generate previews for everything Only generate for favorites or frequently viewed ``` ### Speed Up Initial Sync **First sync only:** ```bash # Use compression syncoid --compress=lz4 \ --sshkey "${SSH_KEY}" \ "root@${NETGRIMOIRE}:vault/Green/Pocket" \ "vaultpg/Green/Pocket" ``` **Subsequent syncs are incremental (much faster).** ### Reduce Preview Generation Load **On Netgrimoire:** - Generate previews during off-hours (overnight) - Use Stash Task Scheduler - Limit concurrent preview generation - Lower thread count for generation - Settings → System → Parallel Tasks: 4 (instead of 8+) --- ## Maintenance ### Weekly (While at Home) **On Netgrimoire:** ```bash # Check both Stash instances running docker ps | grep stash # Verify Pocket directory health du -sh /export/vault/Green/Pocket/ zfs list | grep Pocket # Check for database integrity (optional) # Stash-Main: http://netgrimoire.local:9999 → Tasks → Optimize Database # Stash-Pocket: http://netgrimoire.local:9998 → Tasks → Optimize Database ``` **On Pocket Grimoire:** ```bash # Verify sync is working tail -n 100 /var/log/pocketgrimoire-sync.log # Check Stash accessible curl -s http://localhost:9999 | grep -i stash # Check storage usage df -h /srv/vaultpg ``` ### Monthly **On Netgrimoire:** ```bash # Run manual scan if auto-scan disabled # Stash-Pocket: Tasks → Scan # Clean up orphaned files (if any) # Tasks → Clean # Check database integrity # Tasks → Optimize Database # ZFS scrub sudo zfs scrub vault/Green/Pocket ``` **On Pocket Grimoire:** ```bash # Verify dataset health sudo zpool status vaultpg # Check for errors in sync logs grep -i error /var/log/pocketgrimoire-sync.log # Test Stash browsing and preview playback ``` ### Before Each Trip **On Netgrimoire:** - [ ] Curate new content to Pocket media directory - [ ] Scan Stash-Pocket to pick up new files - [ ] Generate previews for new content - [ ] Verify previews completed: `http://netgrimoire.local:9998` - [ ] Manually trigger sync: `sudo systemctl start pocketgrimoire-sync.service` - [ ] Wait for sync completion (check logs) - [ ] Verify on Pocket: `http://pocket-grimoire.local:9999` **On Pocket Grimoire:** - [ ] Test Stash loads and browses correctly - [ ] Test preview playback - [ ] Test StashApp on Onn boxes connects - [ ] Verify media files accessible ### After Trips **On Pocket Grimoire:** - Check sync logs for any errors during trip - No action needed - sync continues automatically **On Netgrimoire:** - Review what content was most useful - Curate more similar content for next trip - Remove old/unwanted content from Pocket directory --- ## Comparison: Single Dataset vs Two Instances ### Why Not Just One Stash Instance? **Option A: Single Stash watching everything (NOT recommended):** ``` One Stash instance ├── Watches all media (home + pocket) ├── Huge database (slow) ├── Long scan times └── Everything syncs (or nothing does) ``` **Problems:** - ❌ Can't sync just travel subset - ❌ Full database is massive (slow on Pi) - ❌ Scanning entire library takes hours - ❌ No clear separation of content **Option B: Two instances (RECOMMENDED - this guide):** ``` Stash-Main Stash-Pocket ├── All media ├── Pocket media only ├── Large database ├── Small database ├── Stays on Netgrimoire ├── Syncs to Pocket └── Full features └── Read-only on travel ``` **Benefits:** - ✅ Clear separation of home vs travel - ✅ Smaller Pocket database (faster, lighter) - ✅ Only travel data syncs - ✅ Independent organization - ✅ Preview travel setup before trips --- ## Summary ### What You Get with Two-Instance Stash **At Home (Netgrimoire):** - ✅ Stash-Main: Full library management (port 9999) - ✅ Stash-Pocket: Travel subset preview (port 9998) - ✅ Heavy operations (scanning, previews) on powerful hardware - ✅ Independent databases and organizations **On Travel (Pocket Grimoire):** - ✅ Stash-Pocket: Full browsing of travel library (port 9999) - ✅ All previews and metadata available offline - ✅ Zero CPU load (read-only, no generation) - ✅ Works with StashApp on Onn boxes - ✅ Automatic sync every 6 hours when connected **Storage:** - Vault SSD: ~510GB-1.1TB (Stash + media + other data) - Fits comfortably on 1-2TB Vault SSD - Stash-Main data stays on Netgrimoire (doesn't sync) **Maintenance:** - Curate travel content on Netgrimoire - Scan and generate previews there - Automatic sync handles replication - Read-only consumption on travel - No manual database management needed --- ## What This Guide Provides ✅ **Two-instance architecture** (Main at home, Pocket for travel) ✅ **Single sync path** (everything in `/export/vault/Green/Pocket/`) ✅ **Automatic replication** (existing ZFS sync handles it) ✅ **Path consistency** (same relative paths on both systems) ✅ **Read-only travel mode** (browse only, no writes) ✅ **Complete Docker Compose files** for all three instances ✅ **No symlinks needed** (media stored directly in Pocket directory) ✅ **Professional setup** (separation of concerns, clear organization) --- *This guide supplements the main Pocket Grimoire deployment guide. Ensure main guide is completed before adding Stash.* --- ## Architecture ``` ┌─────────────────────────────────────────┐ │ NETGRIMOIRE (Home - Heavy Lifting) │ ├─────────────────────────────────────────┤ │ Stash Container: │ │ - Full scanning │ │ - Preview generation │ │ - Scene detection │ │ - Database writes │ │ - All CPU/GPU intensive work │ │ │ │ ZFS Dataset: vault/stash │ │ - Stash database │ │ - Generated previews │ │ - Thumbnails & sprites │ │ - Scene markers │ └─────────────────────────────────────────┘ ↓ ZFS Send/Receive (via syncoid every 6 hours) ↓ ┌─────────────────────────────────────────┐ │ POCKET GRIMOIRE (Travel - Read Only) │ ├─────────────────────────────────────────┤ │ Stash Container: │ │ - Read-only mode │ │ - No scanning │ │ - No generation │ │ - Just browse existing data │ │ │ │ ZFS Dataset: vaultpg/stash │ │ - Mirrored from Netgrimoire │ │ - Complete database replica │ │ - All previews pre-generated │ └─────────────────────────────────────────┘ ``` --- ## Storage Requirements ### On Netgrimoire ``` Database: 500MB - 2GB (depends on library size) Generated previews: 5GB - 50GB (depends on preview settings) Blobs/markers: 1GB - 10GB ─────────────────────────────────────────────────────── Total: 6.5GB - 62GB ``` ### On Pocket Grimoire ``` Same as Netgrimoire (full replica via ZFS) Stored on Vault SSD (vaultpg pool) ``` ### Sync Bandwidth - **Initial sync:** 10-30GB (1-2 hours on gigabit LAN) - **Incremental sync:** 50MB - 500MB per 6 hours (2-10 minutes) - **After adding 10 videos:** ~210MB (database + previews) --- ## Resource Impact ### Updated Resource Profile (With Stash) **Idle:** ``` Wiki.js + PostgreSQL: ~250MB RAM Jellyfin (idle): ~150MB RAM Stash (read-only): ~200MB RAM # Much lighter than active Stash ZFS ARC: ~512MB RAM System: ~200MB RAM ───────────────────────────────────────── Total: ~1.3GB / 8GB RAM ✓ CPU: <10% Temperature: Cool ``` **Browsing Stash:** ``` Stash (active): ~300MB RAM Other services: ~1.1GB RAM ───────────────────────────────────────── Total: ~1.4GB / 8GB RAM ✓ CPU: <15% Temperature: Cool to Warm ``` **Media Playback + Stash Browsing:** ``` Jellyfin (serving): ~200MB RAM Stash (active): ~300MB RAM Wiki.js + PostgreSQL: ~250MB RAM ZFS ARC: ~512MB RAM System: ~200MB RAM ───────────────────────────────────────── Total: ~1.5GB / 8GB RAM ✓ Still plenty of headroom ``` --- ## Installation: Netgrimoire (Home) ### 1. Create ZFS Datasets ```bash # On Netgrimoire sudo zfs create -o recordsize=16K vault/stash sudo zfs create -o recordsize=16K vault/stash/config # Database sudo zfs create -o recordsize=1M vault/stash/generated # Previews sudo zfs create -o recordsize=128K vault/stash/blobs # Scene markers sudo zfs create vault/stash/cache # Temporary (won't replicate) # Set appropriate permissions sudo chown -R 1000:1000 /vault/stash ``` **Why different recordsizes:** - **16K** for config (SQLite database performs best with small records) - **1M** for generated (large video preview files) - **128K** for blobs (medium-sized screenshots and markers) ### 2. Create Stash Docker Compose ```bash mkdir -p /srv/netgrimoire/stacks/stash nano /srv/netgrimoire/stacks/stash/docker-compose.yml ``` ```yaml services: stash: image: stashapp/stash:latest container_name: netgrimoire_stash environment: - STASH_STASH=/data/ - STASH_GENERATED=/generated/ - STASH_CACHE=/cache/ - STASH_BLOBS=/blobs/ - TZ=America/Chicago volumes: - /vault/stash/config:/root/.stash - /vault/stash/generated:/generated - /vault/stash/cache:/cache - /vault/stash/blobs:/blobs - /vault/media:/data:ro # Your media library (read-only) ports: - "9999:9999" restart: unless-stopped ``` **Start Stash:** ```bash cd /srv/netgrimoire/stacks/stash docker compose up -d ``` ### 3. Configure Stash 1. **Access Stash:** - Open browser: `http://netgrimoire.local:9999` - Complete initial setup wizard 2. **Add Library:** - Settings → Library - Add folder: `/data/library/movies` (or your media path) - Save 3. **Configure Previews:** - Settings → Tasks → Generate - Preview Generation: Enable - Preview Settings: - Video encoding: VP9 or H.264 - Resolution: 720p (good quality, reasonable size) - Segment duration: 10 seconds - Generate image previews: Enable - Generate sprites: Enable 4. **Run Initial Scan:** - Tasks → Scan - Wait for completion (can take hours depending on library size) 5. **Generate Previews:** - Tasks → Generate → Generate Previews - This is CPU intensive - let run at home - Can take many hours depending on library size 6. **Optional: Scene Detection:** - Tasks → Generate → Auto Tag - Scene detection, performer matching, etc. - Very CPU intensive, run at home only ### 4. Take ZFS Snapshots (Optional but Recommended) ```bash # After initial scan and preview generation sudo zfs snapshot vault/stash/config@initial sudo zfs snapshot vault/stash/generated@initial sudo zfs snapshot vault/stash/blobs@initial ``` --- ## Installation: Pocket Grimoire (Travel) ### 1. Create ZFS Datasets ```bash # On Pocket Grimoire sudo zfs create -o recordsize=16K vaultpg/stash sudo zfs create -o recordsize=16K vaultpg/stash/config sudo zfs create -o recordsize=1M vaultpg/stash/generated sudo zfs create -o recordsize=128K vaultpg/stash/blobs sudo zfs create vaultpg/stash/cache # Local cache only, not synced # Set permissions sudo chown -R 1000:1000 /srv/vaultpg/stash ``` ### 2. Create Stash Docker Compose (Read-Only) ```bash mkdir -p /srv/pocket-grimoire/stacks/stash nano /srv/pocket-grimoire/stacks/stash/docker-compose.yml ``` ```yaml services: stash: image: stashapp/stash:latest container_name: pocketgrimoire_stash environment: - STASH_STASH=/data/ - STASH_GENERATED=/generated/ - STASH_CACHE=/cache/ - STASH_BLOBS=/blobs/ - TZ=America/Chicago volumes: - /srv/vaultpg/stash/config:/root/.stash:ro # READ-ONLY - /srv/vaultpg/stash/generated:/generated:ro # READ-ONLY - /srv/vaultpg/stash/blobs:/blobs:ro # READ-ONLY - /srv/pocket-grimoire/data/stash/cache:/cache # Local cache (writable) - /srv/mediapg:/data:ro # Media (already present, read-only) ports: - "9999:9999" restart: unless-stopped ``` **Note the `:ro` flags** - Filesystem is mounted read-only, preventing any writes. **Start Stash:** ```bash cd /srv/pocket-grimoire/stacks/stash docker compose up -d ``` ### 3. Configure Stash for Read-Only Operation **After first start:** 1. **Access Stash:** - Open browser: `http://pocket-grimoire.local:9999` - Should show library from Netgrimoire (after first sync) 2. **Disable Background Tasks:** - Settings → Tasks - Disable all automatic tasks: - ❌ Auto-scan - ❌ Auto-tag - ❌ Auto-preview generation - ❌ Auto-cleanup 3. **Verify Read-Only:** - Try to edit a scene or performer - Should fail with permission error - This confirms read-only mode working --- ## ZFS Replication Configuration ### Update Sync Script Edit your existing sync script to include Stash datasets: ```bash sudo nano /usr/local/sbin/pocketgrimoire-zfs-pull.sh ``` Add these lines: ```bash #!/usr/bin/env bash set -euo pipefail SRC_HOST="netgrimoire.local" SSH_KEY="/srv/pocket-grimoire/keys/zfs_pull_ro" # Existing vault data syncs... syncoid --no-sync-snap --recursive \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/docs" \ "vaultpg/mirror/docs" syncoid --no-sync-snap --recursive \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/photos" \ "vaultpg/mirror/photos" # NEW: Stash database and generated content syncoid --no-sync-snap \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/stash/config" \ "vaultpg/stash/config" syncoid --no-sync-snap \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/stash/generated" \ "vaultpg/stash/generated" syncoid --no-sync-snap \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/stash/blobs" \ "vaultpg/stash/blobs" # Note: We skip cache dataset (temporary data, not needed on Pocket) ``` **Sync runs automatically every 6 hours** via existing systemd timer. ### Manual Sync (For Testing) ```bash # Trigger sync immediately sudo systemctl start pocketgrimoire-sync.service # Watch progress tail -f /var/log/pocketgrimoire-sync.log # Verify Stash data synced ls -lh /srv/vaultpg/stash/config ls -lh /srv/vaultpg/stash/generated ``` --- ## Media Path Consistency **Critical:** Media paths must be consistent between Netgrimoire and Pocket Grimoire. ### Option 1: Matching Paths **If your media is in same location:** ``` Netgrimoire: /vault/media/library/ Pocket: /srv/mediapg/library/ ``` **Stash stores absolute paths** - ensure they match or use symlinks. ### Option 2: Symlinks ```bash # On Pocket Grimoire sudo ln -s /srv/mediapg /vault/media ``` This makes `/vault/media` point to `/srv/mediapg`, matching Netgrimoire's paths. ### Option 3: Stash Path Mapping (If Stash supports it) Some versions of Stash support path mapping in config. Check Stash documentation. --- ## Workflow ### At Home (Before Trips) **On Netgrimoire:** 1. Add new media to library 2. Stash auto-scans (or trigger manually) 3. Previews generate automatically (or trigger manually) 4. Tag/organize content as desired 5. Everything happens in background **Pocket Grimoire (automatic):** 1. Every 6 hours: syncoid pulls changes from Netgrimoire 2. Stash database updated 3. New previews synced 4. Scene markers updated 5. Ready for next trip - no manual intervention ### While Traveling **On Pocket Grimoire:** 1. Access Stash: `http://pocket-grimoire.local:9999` 2. Browse library, tags, performers, studios 3. View previews and scene markers 4. Click to play via Jellyfin or external player 5. **Cannot:** Scan, edit tags, generate previews (read-only) **If you need to edit:** 1. VPN back to Netgrimoire (via WireGuard) 2. Access Netgrimoire Stash: `http://netgrimoire.local:9999` 3. Make changes there 4. Changes sync on next 6-hour cycle ### After Returning Home 1. Sync happens automatically 2. Any changes made on Netgrimoire while away are pulled 3. Pocket Grimoire stays up-to-date 4. No manual intervention required --- ## Accessing Stash ### From Onn Streaming Boxes **Install StashApp for Android TV:** - See "Onn 4K Streaming Box Setup Guide" for detailed instructions - Download APK from: https://github.com/damontecres/StashAppAndroidTV/releases - Sideload onto Onn boxes - Configure server: `http://pocket-grimoire.local:9999` ### From Laptop **Via Web Browser:** - Open: `http://pocket-grimoire.local:9999` - Full Stash web interface available - Same as Netgrimoire, but read-only ### From Phone/Tablet **Via Web Browser:** - Connect to portapotty WiFi - Open: `http://pocket-grimoire.local:9999` - Mobile-responsive interface --- ## Updated Service Access Summary **When connected to portapotty network:** ``` Wiki.js: http://pocket-grimoire.local:3000 Jellyfin: http://pocket-grimoire.local:8096 Stash: http://pocket-grimoire.local:9999 ← NEW File Browser: http://pocket-grimoire.local:8080 Dozzle: http://pocket-grimoire.local:8888 SSH: ssh user@pocket-grimoire.local NFS Media: nfs://pocket-grimoire.local/srv/mediapg Router Admin: http://192.168.8.1 ``` --- ## Troubleshooting ### Stash Won't Start **Check Docker container status:** ```bash docker ps | grep stash docker logs pocketgrimoire_stash ``` **Common issues:** - ZFS datasets not mounted: `zfs mount -a` - Permission denied: `sudo chown -R 1000:1000 /srv/vaultpg/stash` - Port conflict: Another service using port 9999 ### Stash Shows "Database is locked" **This means read-only mode is working correctly.** If you need to make changes: 1. VPN to Netgrimoire 2. Edit on Netgrimoire Stash 3. Changes sync to Pocket on next cycle ### Previews Not Showing **Verify previews synced:** ```bash ls /srv/vaultpg/stash/generated/ # Should show many .webp or .mp4 files ``` **If empty:** - Previews not generated on Netgrimoire yet - Sync hasn't completed (check sync logs) - Check: `tail -n 200 /var/log/pocketgrimoire-sync.log` ### Media Files Not Found **Check paths match:** ```bash # On Netgrimoire, Stash sees files at: # /vault/media/library/movies/ # On Pocket, files are at: # /srv/mediapg/library/movies/ # Create symlink to match: sudo ln -s /srv/mediapg /vault/media ``` **Or verify Docker volume mount:** ```bash docker inspect pocketgrimoire_stash | grep -A 10 Mounts # Should show /srv/mediapg mounted as /data ``` ### Sync Takes Too Long **Check what's being synced:** ```bash # Watch sync in progress sudo zfs list -t snapshot | grep stash # Check dataset sizes sudo zfs list | grep stash ``` **Optimization:** - Reduce preview quality on Netgrimoire (smaller files) - Sync less frequently (change timer from 6h to 12h) - Only sync when on fast network (manual trigger) ### Stash API Key Issues **If StashApp asks for API key:** 1. **Find API key on Netgrimoire:** ```bash # On Netgrimoire cat /vault/stash/config/config.yml | grep api_key ``` 2. **Or via Stash web UI:** - Settings → Security → API Key - Generate key if not present - Copy key 3. **Configure StashApp:** - Settings → Server → API Key - Paste key from Netgrimoire **Note:** API key is in config, which syncs to Pocket, so should be the same. --- ## Optimization Tips ### Reduce Storage Usage **On Netgrimoire (affects Pocket via sync):** 1. **Lower preview quality:** - Settings → Tasks → Generate - Video resolution: 480p instead of 720p - Lower bitrate - Smaller file sizes = faster sync 2. **Disable sprite generation:** - Settings → Tasks → Generate - Disable sprite generation (just use video previews) - Saves significant space 3. **Limit preview duration:** - Settings → Tasks → Generate - Preview duration: 20 seconds instead of 60 seconds - Smaller files ### Speed Up Sync **Initial sync optimization:** ```bash # First sync: Compress during transfer syncoid --compress=lz4 \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/stash/generated" \ "vaultpg/stash/generated" ``` **Bandwidth limiting (if needed):** ```bash # Limit to 10MB/s syncoid --bwlimit=10M \ --sshkey "${SSH_KEY}" \ "root@${SRC_HOST}:vault/stash/config" \ "vaultpg/stash/config" ``` ### Reduce Preview Generation Load **On Netgrimoire:** - Generate previews during off-hours (nightly) - Use Task Scheduler in Stash - Limit concurrent preview generation - Lower thread count for generation --- ## Maintenance ### Weekly **On Netgrimoire:** - Check Stash is running: `docker ps | grep stash` - Verify previews generating (if auto-enabled) - Check disk usage: `zfs list | grep stash` **On Pocket Grimoire:** - Verify sync is working: `tail /var/log/pocketgrimoire-sync.log` - Check Stash is accessible: `http://pocket-grimoire.local:9999` ### Monthly **On Netgrimoire:** - Run manual scan if auto-scan disabled - Clean up orphaned files: Tasks → Clean - Check database integrity: Tasks → Optimize Database - ZFS scrub: `sudo zfs scrub vault/stash` **On Pocket Grimoire:** - Verify dataset health: `sudo zpool status vaultpg` - Check sync logs for errors - Test Stash browsing and preview playback ### Before Trips - [ ] Run scan on Netgrimoire (capture new content) - [ ] Generate previews for new content - [ ] Verify sync completed successfully - [ ] Test Stash on Pocket Grimoire - [ ] Verify StashApp on Onn boxes connects ### After Trips - Check sync logs for any errors during trip - No action needed - sync continues automatically --- ## Alternative: Manual Database Export (Not Recommended) **If ZFS replication is not available:** You can manually export/import Stash database: ```bash # On Netgrimoire - Export sqlite3 /vault/stash/config/stash-go.sqlite ".backup /tmp/stash-backup.db" scp /tmp/stash-backup.db pocket-grimoire:/tmp/ # On Pocket Grimoire - Import docker compose down cp /tmp/stash-backup.db /srv/vaultpg/stash/config/stash-go.sqlite docker compose up -d ``` **Why this is not recommended:** - Manual process (error-prone) - Doesn't sync previews/blobs automatically - Must copy those separately (tens of GB) - ZFS replication is much cleaner --- ## Summary **What you get with Stash on Pocket Grimoire:** - ✅ Full Stash browsing offline - ✅ All previews and metadata available - ✅ Zero CPU load on Pi (read-only) - ✅ Automatic synchronization - ✅ Professional media library management - ✅ Scene markers and performer tagging - ✅ Works with StashApp on Onn boxes **What you give up:** - ❌ Cannot edit/tag while traveling (must VPN to Netgrimoire) - ❌ Cannot generate previews on travel (shouldn't anyway) - ❌ 10-30GB additional storage on Vault SSD - ❌ Slightly more complex setup (but worth it) **Recommended for:** - Large media libraries that need organization - Users who want professional media management - Those who already use or want to use Stash - Anyone who values rich metadata and previews **Skip if:** - Just want simple media playback (Jellyfin is enough) - Very limited storage on Vault SSD - Don't want complexity of ZFS replication - Don't need tagging/scene detection features --- *This guide supplements the main Pocket Grimoire deployment guide. Ensure main guide is completed before adding Stash.*