true bidirectional with split truth modle set up. all scripts are fully bidirectional

This commit is contained in:
2026-04-21 18:20:47 -04:00
parent 6b36b8c07a
commit d4bf31a5f4
9 changed files with 846 additions and 161 deletions
+116 -3
View File
@@ -180,9 +180,36 @@ Remote returns → FAILOVER_HANDBACK_STRIKES consecutive stable checks
**The hardware doesn't need to match.** `/mnt/user/` abstracts everything. A share called `Movies` is `/mnt/user/Movies` on both servers regardless of what drives or pools back it. rsync syncs the content. Container mounts use the same path. The hardware underneath is irrelevant.
**The shared media library and split source of truth:**
**Media library configurations — multiple valid setups:**
Each server owns specific shares as source of truth — managed by their own arrs. The other server mirrors those shares and treats them as read only in normal operation.
The ecosystem supports several library arrangements. The right choice depends on how the two servers and their users relate to each other. All configurations use the same scripts — `HOST1_DAILY_SYNC_SHARES` and `HOST2_DAILY_SYNC_SHARES` in `Master.conf` define who owns what.
---
**Configuration A — Single source, one owner (simplest):**
One server owns all media. The other mirrors everything and piggybacks.
```
HOST1 owns everything:
Movies, Tv_Shows, Music, Anime — all managed by HOST1's arrs
HOST2 mirrors all shares — read only in normal operation
HOST2 arrs disabled or not running
HOST1_DAILY_SYNC_SHARES=(Movies Tv_Shows Music Anime_Shows Anime_Movies ...)
HOST2_DAILY_SYNC_SHARES=() ← nothing — HOST2 owns nothing
Best for:
One person running both servers
Secondary server is pure failover + piggybacking
Simpler arr management — one set of arrs, one library
```
---
**Configuration B — Split source of truth (this setup):**
Each server owns specific shares — managed by their own arrs. The other mirrors those shares read only.
```
HOST1 source of truth: HOST2 source of truth:
@@ -197,7 +224,7 @@ Both servers run arrs simultaneously — no conflict because they manage complet
```
HOST2 arrs: midnight → noon downloading and managing anime
HOST1 Tdarr: 12:30 → 23:00 transcoding anime, syncs as source of truth
HOST1 Tdarr: 12:30 → 23:00 transcoding, syncs as source of truth
```
**The rule is not "don't run arrs on both servers" — it's:**
@@ -212,6 +239,51 @@ HOST2 /mnt/user/Anime_Shows → rsync → HOST1 /mnt/user/Anime_Shows
At Tier 4 failover (18hr+ outage) each server's arr copies spin up to cover the other's shares — but only when the truth holder has genuinely been down long enough to need it.
---
**Configuration C — Weighted split:**
One server owns most shares, the other owns a smaller subset. Same mechanics as B — just an unequal split based on what each person actually manages.
```
HOST1 owns: Movies, Tv_Shows, Music, Kids_Movies, Stand-up, Sports
HOST2 owns: Anime_Shows, Anime_Movies
HOST1_DAILY_SYNC_SHARES=(Movies Tv_Shows Music Kids_Movies ...)
HOST2_DAILY_SYNC_SHARES=(Anime_Shows Anime_Movies)
```
Most real-world split setups will land here — one person has a larger collection, the other a specific niche.
---
**Configuration D — Fully shared, no split:**
Both servers have access to all media but neither "owns" it in a managed sense. No arrs running on either for the shared shares. Content added manually or by one designated manager.
```
HOST1_DAILY_SYNC_SHARES=(Movies Tv_Shows Music ...)
HOST2_DAILY_SYNC_SHARES=()
One-way push — HOST1 is the single truth holder
HOST2 is a read-only mirror for all media
Simpler than split — no arr coordination needed
```
---
**What all configurations have in common:**
```
Same share names on both servers ← /mnt/user/Movies everywhere
Same container names on both servers ← Emby, NginxProxyManager everywhere
HOST*_DAILY_SYNC_SHARES defines truth ← who pushes what, automatically
daily_sync.sh reads the correct list ← direction determined at runtime
Failover Tier 4 uses opposing list ← writeback always correct direction
```
The scripts don't need to know which configuration you're running. The arrays in `Master.conf` define the truth holders — everything else follows automatically.
**Container naming convention:**
```
@@ -441,6 +513,47 @@ Unraid_Scripts/
**Bidirectional.** Both servers run identical scripts. `detect_hosts()` determines local vs remote at runtime. One codebase covers both directions.
**Exact naming consistency across both servers — non-negotiable.**
This is the most important operational principle and the one most likely to cause problems if ignored. The ecosystem is built on the assumption that containers and shares have identical names on both servers.
```
Container names:
Emby ← HOST1 and HOST2
Mariadb-Authelia ← HOST1 and HOST2
Lldap-Gmer4Lfe ← HOST1 and HOST2
NginxProxyManager ← HOST1 and HOST2
Share names:
/mnt/user/Movies ← HOST1 and HOST2
/mnt/user/Tv_Shows ← HOST1 and HOST2
/mnt/user/Anime_Shows ← HOST1 and HOST2
```
Why this matters:
```
rsync.sh: pushes /mnt/user/Movies → remote /mnt/user/Movies
same path, both sides — no mapping, no translation
Container stops:
PROFILE_CRITICAL_CONTAINER_NAMES stops "Emby" locally
then stops "Emby" on remote
one list, both servers, no duplication
failover.sh: starts "Emby" on covering server
same name it always has everywhere
detect_hosts(): compares hostname against HOST1/HOST2 in Master.conf
exact string match — hostnames must match exactly
```
Years of running with custom per-user share paths (`/mnt/user/me/movies`, `/mnt/user/jayred/movies`) taught the hard lesson — every difference becomes a maintenance burden. Every script needs to know about it. Every rsync needs a custom path. Every container stop list diverges.
Shared media shares should be shared — identical paths, identical names, no ownership prefix. User-specific data belongs in personal encrypted shares that are explicitly separate from the shared ecosystem. That boundary keeps the common infrastructure simple and the private data private.
If a container or share has a different name on one server — the script either skips it gracefully or fails to find it. It will not error catastrophically, but it also will not do what you expect. Consistent naming is what makes one codebase work on both servers without modification.
**Self-healing layers.** Problems are addressed at the most targeted level first:
```
docker_watchdog.sh — container level, minimal disruption