# NAS Connection Strategies Summary of how each service connects to the unRAID NAS (192.168.1.192 / 192.168.1.4). --- ## Strategy Overview | Strategy | Services | Reliability | Notes | |----------|----------|-------------|-------| | Docker NFS named volume | Plex, qBittorrent, Audiobookshelf | ⚠️ Fragile | Soft mount; stale handles on drive spin-down | | systemd permanent mount + bind | Calibre (import), oCIS, Immich | ✅ Solid | Hard NFS; permanent; no idle cycling | | systemd automount + bind | Backrest, Filebrowser-Colleen-HD | ✅ Solid | CIFS; TimeoutIdleSec=0; never unmounts once triggered | | Local SSD + lsyncd sync | Calibre (library) | ✅ Best | SQLite never touches NFS; NAS copy is read-only replica | --- ## Per-Service Details ### Plex - **Strategy**: Docker NFS named volume (`nas_media`, external) - **NAS path**: `192.168.1.192:/mnt/user/media` - **Mount options**: `nfsvers=4,soft,nolock,timeo=14,rsize=8192,wsize=8192` - **Container path**: `/data` - **Risk**: `soft` + `timeo=14` means EIO after 14 retries × 0.1s = ~1.4s timeout. If unRAID drives spin down, Plex gets I/O errors. Works in practice because Plex opens/closes file handles per-request rather than holding them open. ### qBittorrent (all 3 instances: open, vpn, vpn2) - **Strategy**: Docker NFS named volume (`nas_media`, same as Plex) - **NAS path**: `192.168.1.192:/mnt/user/media` - **Container path**: `/data` - **Risk**: Same as Plex. Active downloads write continuously — more exposure to spin-down EIO than Plex. ### Calibre - **Strategy (library)**: Local SSD + lsyncd one-way sync to NAS - Local: `/srv/calibre/library` → container `/config/Calibre Library` - lsyncd syncs to `/mnt/nas_books/calibre/Calibre Library` within ~15 seconds - SQLite (`metadata.db`, `notes.db`) never touches NFS — eliminates `apsw.IOError` - **Strategy (import)**: systemd permanent NFS mount + Docker bind mount - Host: `/mnt/nas_books/calibre-import` (permanent NFS, no automount) - Container: `/calibre-import` - NAS path: `192.168.1.192:/mnt/user/media/books` - **Mount options**: `nfsvers=3,hard,rw,noatime` - **Why permanent (not automount)**: Docker bind mounts snapshot the mount reference at container start. If autofs cycles between restarts, the container gets a stale handle. Permanent mount avoids this entirely. - **Manual book add** (when auto-add fails): ```bash docker stop calibre docker run --rm \ -v /srv/calibre/library:/config/Calibre\ Library \ -v /mnt/nas_books/calibre-import:/calibre-import \ lscr.io/linuxserver/calibre:latest \ sh -c "cd /opt/calibre && LD_LIBRARY_PATH=/opt/calibre ./calibredb add \ --library-path '/config/Calibre Library' '/calibre-import/' 2>&1" docker start calibre ``` ### Filebrowser-Colleen-HD - **Strategy**: systemd CIFS automount + Docker bind mount - **Host mount**: `/mnt/nas_backup` (CIFS `//192.168.1.192/backup`) - **Container path**: `/folder` - **Mount options**: `vers=3.0,uid=0,gid=0,noperm,noserverino,soft,TimeoutIdleSec=0` - **Why CIFS**: Container runs as root; CIFS with `uid=0,gid=0` maps all files to root - **TimeoutIdleSec=0**: Never auto-unmounts once triggered; safe for persistent container access ### Backrest (backup service) - **Strategy**: systemd CIFS automount + Docker bind mount (same mount as Filebrowser) - **Host mount**: `/mnt/nas_backup/nas-docker-data` - **Container path**: `/backup-export` - **Same CIFS mount as Filebrowser-Colleen-HD** (`mnt-nas_backup`) ### oCIS (ownCloud Infinite Scale) - **Strategy**: systemd permanent NFS mount + Docker bind mount - **Host mount**: `/mnt/nas_owncloud` (permanent NFS, no automount) - **Container path**: `/var/lib/ocis/storage/users` - **NAS path**: `192.168.1.192:/mnt/user/owncloud` - **Mount options**: `nfsvers=3,hard,rw,noatime` - **Local config/index**: `/srv/ocis/data` and `/srv/ocis/config` stay on local SSD ### Immich - **Strategy**: systemd permanent NFS mount + Docker bind mount - **Host mount**: `/mnt/nas_family` (NFS `192.168.1.192:/mnt/user/family`) - **Container path**: `/usr/src/app/upload` → `/mnt/nas_family/immich-library` - **Mount options**: `nfsvers=3,hard,rw,noatime` - **Why permanent (not automount)**: Drive doesn't spin down; permanent mount avoids any autofs cycling risk - **Database**: PostgreSQL on local SSD (`/var/lib/postgresql/data`) — correct, not on NFS ### Audiobookshelf - **Strategy**: Docker NFS named volume - **NAS path**: `192.168.1.192:/mnt/user/media/audiobooks` - **Container path**: `/audiobooks` - **Config/metadata**: Local SSD (`/srv/audiobookshelf/`) — correct --- ## systemd Mount Units | Unit | Type | Share | Status | |------|------|-------|--------| | `mnt-nas_books.mount` | NFS permanent | `:/mnt/user/media/books` | enabled, always up | | `mnt-nas_owncloud.mount` | NFS permanent | `:/mnt/user/owncloud` | enabled, always up | | `mnt-nas_family.mount` | NFS permanent | `:/mnt/user/family` | enabled, always up | | `mnt-nas_library.mount` | CIFS automount | `//192.168.1.192/library` | triggered on access, TimeoutIdleSec=0 | | `mnt-nas_library.automount` | CIFS automount | — | enabled | | `mnt-nas_backup.mount` | CIFS automount | `//192.168.1.192/backup` | triggered on access, TimeoutIdleSec=0 | | `mnt-nas_backup.automount` | CIFS automount | — | enabled | --- ## Known Issues & Gotchas - **Docker NFS named volumes**: The `nas_media` volume uses `soft,nolock,timeo=14,nfsvers=4`. This is fragile — short timeout means EIO on spin-up. Plex/qBittorrent survive because they open/close handles per request. If either starts having I/O errors, migrate to the systemd permanent mount pattern. - **Docker bind mounts + automount = stale handles**: Docker snapshots the mount reference at container start. If autofs cycles (unmount + remount) between container restarts, the container's bind mount goes stale while the host sees the path fine. Fix: use permanent `.mount` (no `.automount`) for any share that Docker containers bind-mount. - **SQLite on NFS**: Never store SQLite databases (calibre `metadata.db`/`notes.db`, any app DB) on NFS. Even with `hard` mounts and NLM locking, transient NFS errors cause `SQLITE_IOERR`. Keep SQLite on local SSD; sync non-SQLite files to NAS if sharing is needed. - **CIFS vs NFS for file permissions**: CIFS enforces server-side ACLs based on the SMB user. Files created via NFS by uid=99 with mode 600 are inaccessible via CIFS. Use NFS when container needs uid-mapped access to NFS-created files. - **lsyncd for NAS sync**: inotify-based, syncs within ~15 seconds of any write. Config at `/etc/lsyncd/lsyncd.conf.lua`. Log at `/var/log/lsyncd.log`. --- ## Recommended Migration (future) Plex, qBittorrent, Immich, and Audiobookshelf all use the fragile Docker NFS named volume pattern. The safer pattern is systemd permanent mount + Docker bind mount (as used by calibre-import and oCIS). This would involve: 1. Create `/mnt/nas_media` systemd permanent mount unit 2. Update compose files to use bind mounts instead of the external `nas_media` volume 3. `docker volume rm nas_media` after redeployment