---
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.*
