commit ef86214caa474b1d376834c8a84bb98eb106f1f0 Author: Myron Blair Date: Thu Jun 4 12:57:47 2026 +0000 Initial commit — MediaStack VM config and documentation VM 113 on PVE1: Sonarr/Radarr/Prowlarr/qBittorrent behind WireGuard VPN. All traffic exits through DO server, bypassing home ISP. NFS exports movies and TV to Jellyfin (VM 112). Co-Authored-By: Claude Sonnet 4.6 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5c94af --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# MediaStack + +Automated media server VM running on PVE1 Proxmox (VM 113). +All traffic routes through WireGuard VPN → DO server — bypasses home ISP entirely. + +## VM Info +| Item | Value | +|------|-------| +| VM ID | 113 | +| Name | MediaStack-35 | +| IP | 10.48.200.35 | +| Hypervisor | PVE1 (10.48.200.90) | +| OS | Ubuntu 24.04 | +| SSH | root via PVE1 key (`ssh -i /root/.ssh/id_rsa root@10.48.200.35` from PVE1) | + +## Services +| Service | Port | Binary | Data | +|---------|------|--------|------| +| qBittorrent | 8080 | `/usr/bin/qbittorrent-nox` | `/home/qbittorrent/.config/qBittorrent/` | +| Sonarr | 8989 | `/opt/Sonarr/Sonarr` | `/var/lib/sonarr` | +| Radarr | 7878 | `/opt/Radarr/Radarr` | `/var/lib/radarr` | +| Prowlarr | 9696 | `/opt/Prowlarr/Prowlarr` | `/var/lib/prowlarr` | +| NFS server | 2049 | nfs-kernel-server | `/etc/exports` | +| JARVIS agent | — | `/opt/jarvis-agent/agent.py` | `/opt/jarvis-agent/` | +| qemu-guest-agent | — | system | — | + +## API Keys +| Service | Key | +|---------|-----| +| Sonarr | `b43e04350a594846b4ee95261c29e9e0` | +| Radarr | `53c4268360444feeae5f98c0cc24e0e3` | +| Prowlarr | `9d0ce6c5660743b5bf1c7951efc62252` | +| qBittorrent | admin / Joker1974!!! | + +## Media Paths +| Purpose | Path | +|---------|------| +| Downloads | `/media/downloads/complete` | +| Movies | `/media/movies` (NFS → Jellyfin) | +| TV Shows | `/media/tv` (NFS → Jellyfin) | +| Music | `/media/music` | + +## Jellyfin NFS Mounts (VM 112, 10.48.200.33) +| Remote | Local mount | +|--------|-------------| +| `10.48.200.35:/media/movies` | `/mnt/mediastack/movies` | +| `10.48.200.35:/media/tv` | `/mnt/mediastack/tv` | + +## WireGuard VPN +- Interface: `wg0`, VM IP: `10.200.0.4/24` +- Routes through **CT110** (WireGuard-19, `10.48.200.19:51821`) → **DO server** (165.22.1.228) +- All internet traffic exits via DO — ISP never sees download activity +- **Kill-switch:** external traffic blocked if VPN drops; LAN `10.48.200.0/24` always allowed +- CT110 public key: `RXxDgIAaie4n0BxBA48rlmt9BJyp2GEktENeQDlc4hA=` +- MediaStack public key: `SjVwsfPvNFDeLxS6vYesiLVrA8BhdYkquSlMCxpeI2Q=` + +## DNS +FortiGate blocks outbound port 53 to external DNS servers. +Fix: dnsmasq installed on PVE1 (10.48.200.90), forwards to Tailscale DNS (100.100.100.100). +MediaStack resolv config: `/etc/systemd/resolved.conf.d/dns.conf` → `DNS=10.48.200.90` + +## Indexer +- IPTorrents configured in Prowlarr via cookie auth +- Prowlarr auto-syncs all indexers to Sonarr and Radarr + +## Known Issues & Fixes +| Issue | Fix | +|-------|-----| +| musl vs glibc binary crash | Use `linux-core-x64` releases (glibc), NOT `linux-musl-x64` | +| WireGuard kill-switch blocks SSH | ACCEPT LAN rule must use `-A` (append), not `-I` (insert), so it runs before the REJECT rule | +| DNS fails on first boot | PVE1 dnsmasq forwards DNS; set `DNS=10.48.200.90` in systemd-resolved | +| qBittorrent random temp password | Permanent password set; login is admin / Joker1974!!! | +| JARVIS agent config keys | Needs `jarvis_url`, `registration_key`, `ssl_verify: false` — see `config/jarvis-agent/config.json.example` | + +## Repository Layout +``` +config/ + wireguard/ wg0.conf (private key redacted) + systemd/ service unit files for all services + nfs/ /etc/exports + dns/ systemd-resolved DNS override + jarvis-agent/ config.json.example +``` diff --git a/config/dns/resolved-dns.conf b/config/dns/resolved-dns.conf new file mode 100644 index 0000000..f9a6286 --- /dev/null +++ b/config/dns/resolved-dns.conf @@ -0,0 +1,3 @@ +[Resolve] +DNS=10.48.200.90 +Domains=~. diff --git a/config/jarvis-agent/config.json.example b/config/jarvis-agent/config.json.example new file mode 100644 index 0000000..cdb9be1 --- /dev/null +++ b/config/jarvis-agent/config.json.example @@ -0,0 +1,12 @@ +{ + "server_url": "https://165.22.1.228", + "host_header": "jarvis.orbishosting.com", + "agent_id": "mediastack_5038de87", + "api_key": "REDACTED", + "agent_type": "linux", + "heartbeat_interval": 10, + "metrics_interval": 30, + "jarvis_url": "https://165.22.1.228", + "registration_key": "REDACTED", + "ssl_verify": false +} \ No newline at end of file diff --git a/config/nfs/exports b/config/nfs/exports new file mode 100644 index 0000000..b4c1015 --- /dev/null +++ b/config/nfs/exports @@ -0,0 +1,2 @@ +/media/movies 10.48.200.33(rw,sync,no_subtree_check,no_root_squash) +/media/tv 10.48.200.33(rw,sync,no_subtree_check,no_root_squash) diff --git a/config/systemd/jarvis-agent.service b/config/systemd/jarvis-agent.service new file mode 100644 index 0000000..72901b0 --- /dev/null +++ b/config/systemd/jarvis-agent.service @@ -0,0 +1,16 @@ +[Unit] +Description=JARVIS Agent +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +ExecStart=/usr/bin/python3 /opt/jarvis-agent/jarvis-agent.py +WorkingDirectory=/opt/jarvis-agent +Restart=always +RestartSec=10 +StartLimitInterval=60 +StartLimitBurst=5 + +[Install] +WantedBy=multi-user.target diff --git a/config/systemd/prowlarr.service b/config/systemd/prowlarr.service new file mode 100644 index 0000000..ac284c4 --- /dev/null +++ b/config/systemd/prowlarr.service @@ -0,0 +1,14 @@ +[Unit] +Description=Prowlarr +After=network.target wg-quick@wg0.service +Requires=wg-quick@wg0.service + +[Service] +User=prowlarr +Group=prowlarr +ExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/config/systemd/qbittorrent.service b/config/systemd/qbittorrent.service new file mode 100644 index 0000000..24ec9aa --- /dev/null +++ b/config/systemd/qbittorrent.service @@ -0,0 +1,14 @@ +[Unit] +Description=qBittorrent-nox +After=network.target wg-quick@wg0.service +Requires=wg-quick@wg0.service + +[Service] +User=qbittorrent +Group=qbittorrent +ExecStart=/usr/bin/qbittorrent-nox --webui-port=8080 +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/config/systemd/radarr.service b/config/systemd/radarr.service new file mode 100644 index 0000000..2299adf --- /dev/null +++ b/config/systemd/radarr.service @@ -0,0 +1,14 @@ +[Unit] +Description=Radarr +After=network.target wg-quick@wg0.service +Requires=wg-quick@wg0.service + +[Service] +User=radarr +Group=radarr +ExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/config/systemd/sonarr.service b/config/systemd/sonarr.service new file mode 100644 index 0000000..d8188ba --- /dev/null +++ b/config/systemd/sonarr.service @@ -0,0 +1,14 @@ +[Unit] +Description=Sonarr +After=network.target wg-quick@wg0.service +Requires=wg-quick@wg0.service + +[Service] +User=sonarr +Group=sonarr +ExecStart=/opt/Sonarr/Sonarr -nobrowser -data=/var/lib/sonarr +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/config/wireguard/wg0.conf b/config/wireguard/wg0.conf new file mode 100644 index 0000000..5a26406 --- /dev/null +++ b/config/wireguard/wg0.conf @@ -0,0 +1,13 @@ +[Interface] +PrivateKey = REDACTED +Address = 10.200.0.4/24 +DNS = 1.1.1.1 + +PostUp = iptables -A OUTPUT -d 10.48.200.0/24 -j ACCEPT; iptables -A OUTPUT ! -o wg0 -m mark ! --mark 0xca6c -m addrtype ! --dst-type LOCAL -j REJECT +PostDown = iptables -D OUTPUT -d 10.48.200.0/24 -j ACCEPT; iptables -D OUTPUT ! -o wg0 -m mark ! --mark 0xca6c -m addrtype ! --dst-type LOCAL -j REJECT + +[Peer] +PublicKey = RXxDgIAaie4n0BxBA48rlmt9BJyp2GEktENeQDlc4hA= +Endpoint = 10.48.200.19:51821 +AllowedIPs = 0.0.0.0/0 +PersistentKeepalive = 25