# MediaServer Полный self-hosted медиасервер на базе K3S: Plex, *arr стек, Transmission, Prowlarr с Hysteria2 SOCKS5 прокси, Overseerr и Samba для LAN-доступа. ## Компоненты | Сервис | Порт | Описание | |---|---|---| | **Plex** | 32400 | Медиасервер — стриминг фильмов, сериалов, музыки | | **Transmission** | 9091 | BitTorrent клиент | | **Sonarr** | 8989 | Менеджер ТВ-сериалов | | **Radarr** | 7878 | Менеджер фильмов | | **Lidarr** | 8686 | Менеджер музыки | | **Bazarr** | 6767 | Менеджер субтитров | | **Prowlarr** | 9696 | Агрегатор индексеров (с Hysteria2 sidecar) | | **Overseerr** | 5055 | Запросы контента — пользовательский интерфейс | | **Samba** | 445 | LAN SMB-шара — доступ с Windows/Mac/Linux | ## Архитектура хранилища Все сервисы используют **один shared PVC** `mediaserver-data` (RWX — NFS). Структура директорий: ``` PVC: mediaserver-data (200Gi) ├── config/ │ ├── plex/ │ ├── transmission/ │ ├── sonarr/ │ ├── radarr/ │ ├── lidarr/ │ ├── bazarr/ │ ├── prowlarr/ │ └── overseerr/ └── data/ ├── downloads/ │ ├── complete/ ← Transmission складывает завершённые │ └── incomplete/ ← Transmission — в процессе ├── movies/ ← Radarr перемещает сюда ├── series/ ← Sonarr перемещает сюда └── music/ ← Lidarr перемещает сюда ``` В каждом контейнере: - `/config` → `subPath: config/` (изолированные конфиги) - `/data` → `subPath: data` (общая директория для всех сервисов) ## Hysteria2 прокси (Prowlarr) Hysteria2 работает как **sidecar-контейнер в Prowlarr поде** — это НЕ cluster-wide VPN, только Prowlarr использует прокси. ``` Prowlarr Pod: ├── prowlarr container ← трекеры через SOCKS5 127.0.0.1:1080 └── hysteria2 container ← SOCKS5 сервер на 127.0.0.1:1080 ``` Init-контейнер автоматически прописывает в `config.xml` Prowlarr: ```xml True Socks5 127.0.0.1 1080 True ``` ### Настройка Hysteria2 сервера #### Способ 1 — URL целиком (Shadowrocket / NekoBox / Hiddify / любой клиент) Скопируй URL из клиента и вставь **одной строкой** в vault: ```yaml # group_vars/all/vault.yml vault_hysteria2_url: "hysteria2://mypassword@vps.example.com:443?insecure=0&obfs=salamander&obfs-password=obfsecret#MyVPS" ``` Ansible автоматически разберёт URL на составные части — `server`, `auth`, `insecure`, `obfs_type`, `obfs_password`. Ничего больше не нужно. Структура URL: ``` hysteria2://PASSWORD@HOST:PORT?insecure=0&obfs=salamander&obfs-password=OBFS_PASS#Name ↑ ↑ ↑ ↑ ↑ ↑ пароль адрес:порт TLS (0/1) тип obfs пароль obfs метка (игн.) ``` | Параметр | Значение | |---|---| | `PASSWORD` | Пароль аутентификации | | `HOST:PORT` | Адрес и порт сервера | | `insecure=1` | Не проверять TLS (self-signed сертификат) | | `insecure=0` | Проверять TLS (Let's Encrypt / доверенный CA) | | `obfs=salamander` | Включить obfuscation — скрывает протокол от DPI | | `obfs-password=...` | Пароль obfuscation | | `#Name` | Метка — игнорируется, только для отображения в клиентах | Примеры: ``` # Минимальный — только адрес и пароль hysteria2://mypassword@1.2.3.4:443 # Self-signed сертификат на сервере hysteria2://mypassword@1.2.3.4:443?insecure=1 # С obfuscation salamander hysteria2://mypassword@vps.example.com:443?obfs=salamander&obfs-password=obfsecret # Полный вариант hysteria2://mypassword@vps.example.com:443?insecure=0&obfs=salamander&obfs-password=obfsecret#MyVPS ``` --- #### Способ 2 — JSON / inline конфиг Если у тебя есть конфиг в JSON-формате (экспорт из Hiddify, XRay-клиентов и т.д.): ```json { "server": "vps.example.com:443", "auth": "mypassword", "tls": { "insecure": false, "sni": "vps.example.com" }, "obfs": { "type": "salamander", "salamander": { "password": "obfsecret" } }, "socks5": { "listen": "127.0.0.1:1080" } } ``` Маппинг JSON → переменные Ansible: | JSON поле | Ansible переменная | |---|---| | `server` | `vault_hysteria2_server` | | `auth` | `vault_hysteria2_auth` | | `tls.insecure: true` | `mediaserver_hysteria2_insecure: true` | | `obfs.type` | `mediaserver_hysteria2_obfs_type` | | `obfs.salamander.password` | `mediaserver_hysteria2_obfs_password` | --- #### Параметры в `group_vars/all/main.yml` ```yaml # Адрес и порт сервера (из vault) vault_hysteria2_server: "vps.example.com:443" vault_hysteria2_auth: "mypassword" # TLS — пропустить проверку сертификата (self-signed) mediaserver_hysteria2_insecure: false # true если сервер с самоподписанным сертом # Obfuscation (salamander) — скрыть протокол от DPI mediaserver_hysteria2_obfs_type: "salamander" # "" — без obfuscation mediaserver_hysteria2_obfs_password: "obfsecret" # UDP переадресация включена по умолчанию в Hysteria2 # Интервал смены UDP портов (hop) — защита от блокировки по порту # Задаётся в конфиге: transport.udp.hopInterval: 30s ``` Итоговый конфиг, который попадёт в Secret (`hysteria2-secret.yaml.j2`): ```yaml server: vps.example.com:443 auth: mypassword tls: insecure: false # true = игнорировать самоподписанный сертификат obfs: type: salamander salamander: password: obfsecret socks5: listen: 127.0.0.1:1080 # Prowlarr подключается сюда transport: udp: hopInterval: 30s # UDP port hopping каждые 30 сек ``` --- #### Быстрый старт без obfuscation (минимальный пример) ```yaml # vault.yml vault_hysteria2_server: "1.2.3.4:443" vault_hysteria2_auth: "supersecretpassword" ``` ```bash make addon-mediaserver ``` #### С obfuscation salamander ```yaml # vault.yml vault_hysteria2_server: "vps.example.com:443" vault_hysteria2_auth: "supersecretpassword" ``` ```yaml # group_vars/all/main.yml или через ARGS mediaserver_hysteria2_obfs_type: "salamander" mediaserver_hysteria2_obfs_password: "obfs-secret-phrase" ``` ```bash make addon-mediaserver ARGS="-e mediaserver_hysteria2_obfs_type=salamander -e mediaserver_hysteria2_obfs_password=obfs-secret-phrase" ``` #### Self-signed сертификат на сервере ```bash make addon-mediaserver ARGS="-e mediaserver_hysteria2_insecure=true" ``` #### Без прокси (если не нужен) ```bash make addon-mediaserver ARGS="-e mediaserver_hysteria2_enabled=false" ``` ## Установка ### 1. Vault секреты Добавь в `group_vars/all/vault.yml`: ```yaml # Plex claim — получить на https://plex.tv/claim (действует 4 минуты) vault_plex_claim_token: "claim-xxxxxxxxxxxxxxxxx" # Hysteria2 сервер (пропусти если не нужен прокси) vault_hysteria2_server: "your-server.com:443" vault_hysteria2_auth: "your-password" # Samba пароль vault_samba_password: "my-samba-password" # Transmission пароль vault_transmission_password: "my-torrent-password" ``` ### 2. Включить аддон ```yaml # group_vars/all/addons.yml addon_mediaserver: true ``` ### 3. Деплой ```bash make addon-mediaserver ``` Без Hysteria2 прокси: ```bash make addon-mediaserver ARGS="-e mediaserver_hysteria2_enabled=false" ``` ## Настройка ### Основные параметры (`group_vars/all/main.yml` или ARGS) ```yaml mediaserver_namespace: "mediaserver" mediaserver_data_size: "200Gi" # размер shared PVC mediaserver_storage_class: "" # пусто = default StorageClass (nfs-master01) mediaserver_timezone: "Europe/Moscow" mediaserver_puid: "1000" mediaserver_pgid: "1000" ``` ### Отключить отдельные компоненты ```bash make addon-mediaserver ARGS="-e mediaserver_lidarr_enabled=false -e mediaserver_watchtower_enabled=false" ``` ### Ingress для внешнего доступа ```yaml mediaserver_plex_ingress_enabled: true mediaserver_plex_ingress_host: "plex.example.com" mediaserver_sonarr_ingress_enabled: true mediaserver_sonarr_ingress_host: "sonarr.example.com" mediaserver_ingress_annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/proxy-body-size: "0" ``` ### Samba со статическим IP ```yaml mediaserver_samba_static_ip: "192.168.1.110" # kube-vip выдаст этот IP ``` После деплоя подключение с LAN: ``` Windows: \\192.168.1.110\media Mac: smb://192.168.1.110/media Linux: mount -t cifs //192.168.1.110/media /mnt/media -o user=media ``` ## Интеграция сервисов После установки настрой в UI (однократно): ### Prowlarr → *arr В Prowlarr UI добавь индексеры, затем в **Settings → Apps** добавь каждый *arr: | App | URL | API Key | |---|---|---| | Sonarr | `http://sonarr:8989` | из Settings → General | | Radarr | `http://radarr:7878` | из Settings → General | | Lidarr | `http://lidarr:8686` | из Settings → General | ### Sonarr/Radarr/Lidarr → Transmission В каждом *arr: **Settings → Download Clients → Add → Transmission**: ``` Host: transmission Port: 9091 Username: admin Password: (vault_transmission_password) ``` ### Sonarr/Radarr → Пути В **Settings → Media Management → Root Folders**: | Сервис | Папка | |---|---| | Sonarr | `/data/series` | | Radarr | `/data/movies` | | Lidarr | `/data/music` | В Transmission: папка завершённых загрузок → `/data/downloads/complete` ### Overseerr → Plex + *arr В Overseerr UI при первом входе: 1. Plex URL: `http://plex:32400` 2. Добавь Radarr: `http://radarr:7878` 3. Добавь Sonarr: `http://sonarr:8989` ## Port-forward для начальной настройки ```bash export KUBECONFIG=$(pwd)/kubeconfig # Plex kubectl -n mediaserver port-forward svc/plex 32400:32400 # Sonarr kubectl -n mediaserver port-forward svc/sonarr 8989:8989 # Radarr kubectl -n mediaserver port-forward svc/radarr 7878:7878 # Transmission kubectl -n mediaserver port-forward svc/transmission 9091:9091 # Prowlarr kubectl -n mediaserver port-forward svc/prowlarr 9696:9696 # Overseerr kubectl -n mediaserver port-forward svc/overseerr 5055:5055 ``` ## Проверка Hysteria2 ```bash # Логи Hysteria2 sidecar kubectl -n mediaserver logs -l app.kubernetes.io/name=prowlarr -c hysteria2 -f # Проверить прокси конфиг Prowlarr kubectl -n mediaserver exec -it deployment/prowlarr -c prowlarr -- cat /config/config.xml | grep -i proxy # Тест SOCKS5 через curl внутри pod kubectl -n mediaserver exec -it deployment/prowlarr -c prowlarr -- \ curl --socks5 127.0.0.1:1080 https://ifconfig.me ``` ## Диагностика ```bash # Все поды kubectl -n mediaserver get pods -o wide # Статус PVC kubectl -n mediaserver get pvc # IP Samba kubectl -n mediaserver get svc samba # Логи конкретного сервиса kubectl -n mediaserver logs -l app.kubernetes.io/name=sonarr -f # Перезапуск сервиса kubectl -n mediaserver rollout restart deployment/radarr ``` ## Обновление ```bash # Обновить все компоненты (pull latest images) make addon-mediaserver # Только один сервис make addon-mediaserver ARGS="--tags helm" ``` Автообновление образов — включи Watchtower: ```yaml mediaserver_watchtower_enabled: true mediaserver_watchtower_schedule: "0 0 4 * * *" # 4:00 утра каждый день ``` ## Деинсталляция ```bash export KUBECONFIG=$(pwd)/kubeconfig # Удалить все Helm-релизы for svc in plex transmission sonarr radarr lidarr bazarr prowlarr overseerr watchtower; do helm -n mediaserver uninstall $svc 2>/dev/null || true done # Удалить Samba и PVC kubectl -n mediaserver delete deploy samba kubectl -n mediaserver delete svc samba kubectl -n mediaserver delete secret hysteria2-config # Удалить namespace (удалит и PVC если нет ReclaimPolicy: Retain) kubectl delete namespace mediaserver ``` ## Официальные ресурсы - Официальный сайт: [https://www.plex.tv/](https://www.plex.tv/) - Официальная документация: [https://docs.linuxserver.io/](https://docs.linuxserver.io/) - Версии Helm chart / ПО: [https://docs.linuxserver.io/images/docker-plex/#versions](https://docs.linuxserver.io/images/docker-plex/#versions)