From 1dce1fc5e7398556a4517845b06cb188efd2c0a7 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 1 Sep 2026 23:23:43 +0200 Subject: [PATCH] The media four: plex, sonarr, radarr, qbittorrent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shape they share is the interesting part: a media library is a fact about the machine that several modules mount, so each declares exactly the paths it touches, with one owner and mode across all of them. The host reconciles a directory rather than creating it, so the second module ensuring a path the first already ensured is maintenance, not a fight — and ADR 0030 keeps a shared path alive when one of its sharers is unassigned, because it holds what the mesh did not put there. Plex runs on the machine's own network like home-assistant, and for the same reason: discovery is the point. The other three publish, so the mesh chooses their machine ports. All pinned by real digests, resolved on this workstation today. The catalogue stands at 22, of which the arrangement being replaced ran 95 — but its number counts workstation ricing and one-machine tooling beside services, and only the services convert to manifests like these. --- examples/modules/plex.json | 87 +++++++++++++++++++++++++++++++ examples/modules/qbittorrent.json | 49 +++++++++++++++++ examples/modules/radarr.json | 57 ++++++++++++++++++++ examples/modules/sonarr.json | 65 +++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 examples/modules/plex.json create mode 100644 examples/modules/qbittorrent.json create mode 100644 examples/modules/radarr.json create mode 100644 examples/modules/sonarr.json diff --git a/examples/modules/plex.json b/examples/modules/plex.json new file mode 100644 index 0000000..d1287f3 --- /dev/null +++ b/examples/modules/plex.json @@ -0,0 +1,87 @@ +{ + "module": "plex", + "version": "1", + "capabilities": [ + "container-runtime" + ], + "listens": [ + { + "port": 32400, + "protocol": "tcp", + "from": "mesh", + "why": "streaming and the app; reaching it from outside is a route grant later" + } + ], + "resources": [ + { + "id": "config", + "type": "directory", + "path": "/services/plex/config", + "mode": "0700", + "owner": "1000:1000" + }, + { + "id": "transcode", + "type": "directory", + "path": "/services/plex/transcode", + "mode": "0700", + "owner": "1000:1000" + }, + { + "id": "media-movies", + "type": "directory", + "path": "/services/media/movies", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "media-series", + "type": "directory", + "path": "/services/media/series", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "media-anime", + "type": "directory", + "path": "/services/media/anime", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "media-music", + "type": "directory", + "path": "/services/media/music", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "media-audiobooks", + "type": "directory", + "path": "/services/media/audiobooks", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "server", + "type": "container", + "name": "plex", + "image": "plexinc/pms-docker@sha256:83a425ae9e133b1cb2cc3b809556e01c61cd8ff65c582e41b4374bc2210bac9e", + "network": "host", + "env": { + "PLEX_UID": "1000", + "PLEX_GID": "1000", + "TZ": "Etc/UTC" + }, + "volumes": [ + "/services/plex/config:/config", + "/services/plex/transcode:/transcode", + "/services/media/movies:/movies", + "/services/media/series:/series", + "/services/media/anime:/anime", + "/services/media/music:/music", + "/services/media/audiobooks:/audiobooks" + ] + } + ] +} diff --git a/examples/modules/qbittorrent.json b/examples/modules/qbittorrent.json new file mode 100644 index 0000000..a8e8cb5 --- /dev/null +++ b/examples/modules/qbittorrent.json @@ -0,0 +1,49 @@ +{ + "module": "qbittorrent", + "version": "1", + "capabilities": [ + "container-runtime" + ], + "listens": [ + { + "port": 8080, + "protocol": "tcp", + "from": "mesh", + "why": "the download client's pages" + } + ], + "resources": [ + { + "id": "config", + "type": "directory", + "path": "/services/qbittorrent/config", + "mode": "0700", + "owner": "1000:1000" + }, + { + "id": "media-downloads", + "type": "directory", + "path": "/services/media/downloads", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "server", + "type": "container", + "name": "qbittorrent", + "image": "lscr.io/linuxserver/qbittorrent@sha256:a00b6a597a3832a1814cde0ef60abc55c94644f3f80902c3432f6af6de8d4a96", + "env": { + "PUID": "1000", + "PGID": "1000", + "TZ": "Etc/UTC" + }, + "ports": [ + "8080" + ], + "volumes": [ + "/services/qbittorrent/config:/config", + "/services/media/downloads:/downloads" + ] + } + ] +} diff --git a/examples/modules/radarr.json b/examples/modules/radarr.json new file mode 100644 index 0000000..51a782f --- /dev/null +++ b/examples/modules/radarr.json @@ -0,0 +1,57 @@ +{ + "module": "radarr", + "version": "1", + "capabilities": [ + "container-runtime" + ], + "listens": [ + { + "port": 7878, + "protocol": "tcp", + "from": "mesh", + "why": "managing films" + } + ], + "resources": [ + { + "id": "config", + "type": "directory", + "path": "/services/radarr/config", + "mode": "0700", + "owner": "1000:1000" + }, + { + "id": "media-movies", + "type": "directory", + "path": "/services/media/movies", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "media-downloads", + "type": "directory", + "path": "/services/media/downloads", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "server", + "type": "container", + "name": "radarr", + "image": "lscr.io/linuxserver/radarr@sha256:119aaa4a4f7349bcd2a136c5373a0d7925b5479915c7dfe0c0ad352db2a6d438", + "env": { + "PUID": "1000", + "PGID": "1000", + "TZ": "Etc/UTC" + }, + "ports": [ + "7878" + ], + "volumes": [ + "/services/radarr/config:/config", + "/services/media/movies:/movies", + "/services/media/downloads:/downloads" + ] + } + ] +} diff --git a/examples/modules/sonarr.json b/examples/modules/sonarr.json new file mode 100644 index 0000000..b42fb6c --- /dev/null +++ b/examples/modules/sonarr.json @@ -0,0 +1,65 @@ +{ + "module": "sonarr", + "version": "1", + "capabilities": [ + "container-runtime" + ], + "listens": [ + { + "port": 8989, + "protocol": "tcp", + "from": "mesh", + "why": "managing series" + } + ], + "resources": [ + { + "id": "config", + "type": "directory", + "path": "/services/sonarr/config", + "mode": "0700", + "owner": "1000:1000" + }, + { + "id": "media-series", + "type": "directory", + "path": "/services/media/series", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "media-anime", + "type": "directory", + "path": "/services/media/anime", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "media-downloads", + "type": "directory", + "path": "/services/media/downloads", + "mode": "0755", + "owner": "1000:1000" + }, + { + "id": "server", + "type": "container", + "name": "sonarr", + "image": "lscr.io/linuxserver/sonarr@sha256:c19aa4ecdf03d73e1d5c901da33744cb7eb4d921f89bafed1ca264601d7fa224", + "env": { + "PUID": "1000", + "PGID": "1000", + "TZ": "Etc/UTC" + }, + "ports": [ + "8989" + ], + "volumes": [ + "/services/sonarr/config:/config", + "/services/media/series:/series", + "/services/media/anime:/anime", + "/services/media/downloads:/downloads" + ] + } + ] +}