From 72d540fb85f436a2bf26d613c4e43c718a81c02d Mon Sep 17 00:00:00 2001 From: tommy Date: Fri, 3 Jul 2026 00:12:07 -0500 Subject: [PATCH] 4K quality-first arr stack: radarr-4k + sonarr-4k (Step 1 standup+wiring) Separate instances (ports 7879/8990) on the shared /mnt/media/data hardlink tree. Ansible inline-compose (idempotent). Wired: Prowlarr apps+sync, Overseerr native-4K servers (existing radarr is4k mislabel corrected), separate Plex 4K libraries, Traefik file-provider routers. Tdarr excludes the 4K roots. Recyclarr = deferred Step 2. Co-Authored-By: Claude Opus 4.8 --- arrs-4k/README.md | 30 +++++++++ arrs-4k/deploy-arrs-4k.yml | 86 +++++++++++++++++++++++++ arrs-4k/traefik-router.dynamic_conf.yml | 27 ++++++++ 3 files changed, 143 insertions(+) create mode 100644 arrs-4k/README.md create mode 100644 arrs-4k/deploy-arrs-4k.yml create mode 100644 arrs-4k/traefik-router.dynamic_conf.yml diff --git a/arrs-4k/README.md b/arrs-4k/README.md new file mode 100644 index 0000000..53c413d --- /dev/null +++ b/arrs-4k/README.md @@ -0,0 +1,30 @@ +# 4K Quality-First arr stack — radarr-4k + sonarr-4k + +SEPARATE instances from the untouched 1080p stack (for Overseerr native-4K routing + +isolation). Host: media-server (.183). Deployed by `deploy-arrs-4k.yml` (inline-compose, +idempotent, changed=0). + +## Instances +| | port (host:cont) | URL | root folder | +|---|---|---|---| +| radarr-4k | 7879:7878 | radarr-4k.goattw.net | /data/media/movies-4k | +| sonarr-4k | 8990:8989 | sonarr-4k.goattw.net | /data/media/tv-4k | + +- Image `lscr.io/linuxserver/{radarr,sonarr}:latest`, PUID/PGID 1000, net `traefik_public`. +- Mount `/mnt/media/data -> /data` — SAME single hardlink tree as the 1080p stack + download + clients (st_dev verified identical), so imports are instant hardlinks. NFS from + TrueNAS `Tank/Media`. Roots created 1000:3000 775 (match 1080p). + +## Wiring (Step 1, done) +- **Prowlarr**: `Radarr (4K)`/`Sonarr (4K)` applications (fullSync), indexers synced. +- **Overseerr**: radarr-4k/sonarr-4k as `is4k=true` servers (native 4K routing). The existing + 1080p radarr was mislabeled `is4k=true` and was flipped to `is4k=false` (non-4k default). +- **Plex**: SEPARATE libraries `Movies - 4K` (/data/media/movies-4k) + `TV - 4K` (/data/media/tv-4k), + not merged into the 1080p libraries. +- **Traefik**: file-provider routers (see traefik-router snippet), NOT docker labels. +- **Tdarr**: does NOT watch movies-4k/tv-4k (its libraries are the specific 1080p /media/movies, + /media/tv) — quality-first keeps the grabbed file. + +## Deferred (Step 2 — gated) +Recyclarr 4K config + quality profiles (custom formats, remux tiers). NOT deployed yet. +The Overseerr 4K servers currently point at the default `Ultra-HD` profile as a placeholder. diff --git a/arrs-4k/deploy-arrs-4k.yml b/arrs-4k/deploy-arrs-4k.yml new file mode 100644 index 0000000..87193c0 --- /dev/null +++ b/arrs-4k/deploy-arrs-4k.yml @@ -0,0 +1,86 @@ +--- +- name: Deploy 4K arr instances (radarr-4k, sonarr-4k) on media-server + hosts: media-server + become: true + vars: + app_dir: /home/tommy/arrs-4k + + tasks: + - name: Create arrs-4k directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: tommy + group: tommy + mode: "0755" + loop: + - "{{ app_dir }}" + - "{{ app_dir }}/radarr-4k" + - "{{ app_dir }}/sonarr-4k" + + - name: Write docker-compose.yml + ansible.builtin.copy: + dest: "{{ app_dir }}/docker-compose.yml" + owner: tommy + group: tommy + mode: "0644" + content: | + # 4K Quality-First arr instances — SEPARATE from the untouched 1080p stack. + # Host: media-server (.183). Shares /mnt/media/data -> /data (single hardlink tree). + # Roots: radarr-4k -> /data/media/movies-4k ; sonarr-4k -> /data/media/tv-4k + # Routing: Traefik FILE provider on node01 dynamic_conf.yml (NO docker labels): + # radarr-4k.goattw.net -> 192.168.99.183:7879 ; sonarr-4k.goattw.net -> 192.168.99.183:8990 + # middlewares: secure-headers@file, authelia-auth@file, crowdsec-bouncer@file + # Tdarr does NOT watch movies-4k/tv-4k (quality-first keeps the grabbed file). + + services: + radarr-4k: + image: lscr.io/linuxserver/radarr:latest + container_name: radarr-4k + mem_limit: 1g + cpus: 1.0 + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Chicago + networks: + - traefik_public + volumes: + - ./radarr-4k:/config + - /mnt/media/data:/data + ports: + - "7879:7878/tcp" + restart: unless-stopped + + sonarr-4k: + image: lscr.io/linuxserver/sonarr:latest + container_name: sonarr-4k + mem_limit: 1g + cpus: 1.0 + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Chicago + networks: + - traefik_public + volumes: + - ./sonarr-4k:/config + - /mnt/media/data:/data + ports: + - "8990:8989/tcp" + restart: unless-stopped + + networks: + traefik_public: + external: true + + - name: Deploy 4K arrs with docker compose + community.docker.docker_compose_v2: + project_src: "{{ app_dir }}" + state: present + pull: missing + register: r + + - name: Result + ansible.builtin.debug: + msg: "arrs-4k {{ 'running (changed)' if r.changed else 'already up (no-op)' }}" diff --git a/arrs-4k/traefik-router.dynamic_conf.yml b/arrs-4k/traefik-router.dynamic_conf.yml new file mode 100644 index 0000000..444f4ba --- /dev/null +++ b/arrs-4k/traefik-router.dynamic_conf.yml @@ -0,0 +1,27 @@ +# File-provider routers for the 4K arr UIs — merged into node01 +# /home/tommy/traefik/dynamic_conf.yml (live) under http.routers and http.services. +# NOTE: watcher was flaky on restart-era; `docker restart traefik` after edits to be safe. + +# --- http.routers: --- + radarr-4k: + rule: "Host(`radarr-4k.goattw.net`)" + entryPoints: ["websecure"] + tls: { certResolver: letsencrypt } + service: radarr-4k-service + middlewares: ["secure-headers@file", "authelia-auth@file", "crowdsec-bouncer@file"] + sonarr-4k: + rule: "Host(`sonarr-4k.goattw.net`)" + entryPoints: ["websecure"] + tls: { certResolver: letsencrypt } + service: sonarr-4k-service + middlewares: ["secure-headers@file", "authelia-auth@file", "crowdsec-bouncer@file"] + +# --- http.services: --- + radarr-4k-service: + loadBalancer: + servers: [{ url: "http://192.168.99.183:7879" }] + serversTransport: default-transport + sonarr-4k-service: + loadBalancer: + servers: [{ url: "http://192.168.99.183:8990" }] + serversTransport: default-transport