diff --git a/Netgrimoire/Pocket/Stash_Integration.md b/Netgrimoire/Pocket/Stash_Integration.md index 3c8567f..0af32dc 100644 --- a/Netgrimoire/Pocket/Stash_Integration.md +++ b/Netgrimoire/Pocket/Stash_Integration.md @@ -2,7 +2,7 @@ title: Pocket Clips description: Integrating Stash published: true -date: 2026-02-20T04:48:11.191Z +date: 2026-02-20T12:54:12.016Z tags: editor: markdown dateCreated: 2026-02-20T04:48:11.191Z @@ -10,21 +10,1187 @@ dateCreated: 2026-02-20T04:48:11.191Z # Pocket Grimoire - Stash Integration Guide -**Adding Stash media library manager to Pocket Grimoire using ZFS replication** +**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, a powerful media library manager. The architecture uses ZFS replication to mirror Stash data from Netgrimoire (home) to Pocket Grimoire (travel), allowing: +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 travel content +- **Stash-Pocket** replicates to Pocket Grimoire for offline access -- Full Stash browsing offline -- All previews, thumbnails, and metadata available -- Zero CPU load on Pi (no scanning/generation) -- Automatic synchronization via existing sync jobs -- Read-only operation on travel +This approach provides: +- Full library management at home (Stash-Main) +- Curated travel subset with independent database (Stash-Pocket) +- Automatic synchronization via existing ZFS replication +- Read-only browsing on travel with all previews pre-generated +- Zero CPU load on travel Pi (no scanning/generation) -**Key Principle:** Netgrimoire does all heavy lifting (scanning, preview generation), Pocket Grimoire just serves pre-generated content. +**Key Principle:** All intensive operations happen on Netgrimoire. Pocket Grimoire just serves pre-generated content in read-only mode. + +--- + +## 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 Pocket media │ +│ ├─ Location: /export/vault/Green/Pocket/ │ +│ │ ├── stash/config (database) │ +│ │ ├── stash/generated (previews) │ +│ │ ├── stash/blobs (markers) │ +│ │ └── media/library (curated content) │ +│ ├─ Database: 200MB-1GB (travel subset) │ +│ └─ SYNCS to Pocket via ZFS replication │ +│ │ +└─────────────────────────────────────────────────────┘ + ↓ ZFS Send + (Entire /export/vault/Green/Pocket/ syncs) + ↓ +┌─────────────────────────────────────────────────────┐ +│ POCKET GRIMOIRE (Travel) │ +├─────────────────────────────────────────────────────┤ +│ │ +│ Stash Instance: "Stash-Pocket" (Port 9999) │ +│ ├─ Watches: Pocket media only (read-only) │ +│ ├─ Location: /srv/vaultpg/Green/Pocket/ │ +│ │ ├── stash/config (synced, read-only) │ +│ │ ├── stash/generated (synced, read-only) │ +│ │ ├── stash/blobs (synced, read-only) │ +│ │ └── media/library (synced media files) │ +│ ├─ 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 travel content +- Smaller database (faster, lighter) +- Independent from main library +- Syncs to Pocket Grimoire automatically +- Preview travel setup before trips + +✅ **Separation of Concerns:** +- Main library can be massive (thousands of videos) +- Travel 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 travel 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):** +``` +Location: /export/vault/Green/Pocket/stash/ +Database: 200MB-1GB (smaller subset) +Generated previews: 5-20GB +Blobs/markers: 1-5GB +───────────────────────────────────────────── +Total: ~6-26GB (syncs to Pocket) +``` + +**Pocket Media:** +``` +Location: /export/vault/Green/Pocket/media/ +Content: 500GB-1TB (curated for travel) +───────────────────────────────────────────── +Total Pocket data: ~506GB-1TB (entire Green/Pocket/ directory) +``` + +### On Pocket Grimoire (Vault SSD) + +``` +Location: /srv/vaultpg/Green/Pocket/ +Stash data: ~6-26GB (synced from Netgrimoire) +Media files: ~500GB-1TB (synced from Netgrimoire) +Wiki/photos/docs: ~10-50GB (already syncing) +───────────────────────────────────────────── +Total: ~516GB-1.1TB on Vault SSD + +This fits comfortably on a 1-2TB Vault SSD. +``` + +--- + +## 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 Pocket 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 + +# Create Stash-Pocket directories (IN Pocket folder - will sync) +sudo mkdir -p /export/vault/Green/Pocket/stash/{config,generated,blobs,cache} +sudo mkdir -p /export/vault/Green/Pocket/media/library/{movies,tv} +sudo chown -R 1000:1000 /export/vault/Green/Pocket +sudo chmod -R 755 /export/vault/Green/Pocket +``` + +**Verify structure:** +```bash +tree -L 2 /export/vault/stash-main +tree -L 3 /export/vault/Green/Pocket +``` + +### 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 (READ-ONLY) + - /srv/vaultpg/Green/Pocket/stash/config:/root/.stash:ro + - /srv/vaultpg/Green/Pocket/stash/generated:/generated:ro + - /srv/vaultpg/Green/Pocket/stash/blobs:/blobs:ro + + # Local cache only (writable, not synced) + - /srv/pocket-grimoire/data/stash/cache:/cache + + # Media location (read-only) + - /srv/vaultpg/Green/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" + +# Existing sync - this now includes Stash-Pocket automatically +syncoid --no-sync-snap --recursive \ + --sshkey "${SSH_KEY}" \ + "root@${SRC_HOST}:vault/Green/Pocket" \ + "vaultpg/Green/Pocket" + +# This single command syncs: +# - /export/vault/Green/Pocket/stash/ → Stash-Pocket data +# - /export/vault/Green/Pocket/media/ → Media files +# - /export/vault/Green/Pocket/wiki/ → Wiki content +# - /export/vault/Green/Pocket/photos/ → Photos +# - /export/vault/Green/Pocket/documents/ → Documents +``` + +**No additional sync commands needed!** ✅ + +**Stash-Main data does NOT sync** (it's in `/export/vault/stash-main/`, outside Pocket directory). + +### 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.* ---