Reorganize project structure into logical subdirectories

This commit is contained in:
JaviPege
2025-10-22 10:58:05 +02:00
parent 8f173a864c
commit fd087235d4
13 changed files with 688 additions and 381 deletions

115
CLAUDE.md Normal file
View File

@@ -0,0 +1,115 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
MediaCenter is a Docker-based media streaming stack that leverages Real-Debrid and the *Arr ecosystem to create an "infinite" media library. This is a microservices architecture project using Docker Compose to orchestrate 11 services including Plex, Overseerr, Radarr, Sonarr, Prowlarr, Zilean, Zurg, RDTClient, Recyclarr, Autoscan, and Watchtower.
## Essential Commands
### Initial Setup (Run Once)
```bash
chmod +x setup.sh
./setup.sh
sudo reboot # Required after setup
```
### Stack Management
```bash
# Start the entire stack
docker compose up -d
# Stop the stack
docker compose down
# Monitor logs
docker compose logs -f [service_name]
# Restart individual services
docker compose restart [service_name]
# Update quality profiles
docker compose exec recyclarr recyclarr sync
```
### Debugging and Monitoring
```bash
# Check service health
docker compose ps
# View specific service logs
docker compose logs radarr
docker compose logs sonarr
docker compose logs zurg
# Monitor container resources
docker stats
```
## Architecture & Key Concepts
### Data Flow Pattern
The system uses a **symlink-based architecture** optimized for hardlinking:
1. **Request**: Overseerr → Radarr/Sonarr → Prowlarr → Zilean/Indexers
2. **Download**: RDTClient → Real-Debrid → Zurg → Rclone Mount
3. **Media**: Symlinks → Media folders → Plex → Autoscan refresh
### Directory Structure
```
${ROOT_DIR}/
├── config/ # Container configurations (created by setup.sh)
├── data/
│ ├── symlinks/ # Download symlinks (radarr/, sonarr/)
│ ├── realdebrid-zurg/ # Rclone mount point
│ └── media/ # Final media library (movies/, tv/)
```
### Critical Configuration Files
- **`.env`**: Environment variables, user IDs (13000-13009), Plex claim token
- **`compose.yml`**: Complete Docker stack with dependencies and health checks
- **`zurg.yml`**: Real-Debrid API integration and WebDAV server config
- **`recyclarr/recyclarr.yml`**: Automated quality profiles with TRaSH-Guides compliance
- **`autoscan/config.yml`**: Webhook configuration for Plex library updates
## Service Ports & Access
- Plex: Host Mode (network_mode: host)
- Overseerr: 5055 (Request management)
- Prowlarr: 9696 (Indexer management)
- Radarr: 7878 (Movie management)
- Sonarr: 8989 (TV management)
- RDTClient: 6500 (Download client)
- Zurg: 9999 (Real-Debrid WebDAV interface)
- Zilean: 8181 (Torrent indexer)
## Development Requirements
### Prerequisites
- Active Real-Debrid subscription and API key
- Docker Engine + Docker Compose
- Ubuntu Server (recommended: 8GB RAM, 50GB disk)
- Static IP configuration
### Permission System
The setup.sh script creates users with IDs 13000-13009 and sets critical permissions (775/664, umask 002). All containers run with these user IDs for proper file access.
## Important Notes
### First-Run Behavior
- **Plex claim token**: Valid for only 4 minutes, set in .env before deployment
- **Zilean database**: Initial torrent indexing can take >1.5 days
- **Real-Debrid API**: Must be configured in zurg.yml before starting
### Updates & Maintenance
- **Watchtower**: Automatically updates containers daily at 4 AM
- **Manual updates**: `docker compose pull && docker compose up -d`
- **Quality profiles**: Run `docker compose exec recyclarr recyclarr sync` after changes
### Filesystem Design
The project uses symlinks extensively to maintain hardlink compatibility between download clients and media servers. Never modify the data/symlinks/ structure directly - let Radarr/Sonarr manage these paths.
## No Testing Framework
This is a configuration-heavy deployment project without formal tests. Validation is done through:
- Docker Compose health checks
- Web UI functionality testing
- Integration testing via full stack deployment

View File

@@ -481,7 +481,7 @@ After installation, you can update quality profiles:
```bash
cd /mediacenter
./recyclarr-sync.sh
./scripts/recyclarr-sync.sh
```
### Add More Indexers
@@ -493,9 +493,9 @@ cd /mediacenter
### Customize Quality Settings
Edit `/mediacenter/recyclarr.yml` and run:
Edit `/mediacenter/config/recyclarr.yml` and run:
```bash
./recyclarr-sync.sh
./scripts/recyclarr-sync.sh
```
### Enable Traefik (Reverse Proxy)

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Ashwin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -214,7 +214,7 @@ To manually update profiles after installation:
```bash
cd /YOUR_INSTALL_DIR
./recyclarr-sync.sh
./scripts/recyclarr-sync.sh
```
## Directory Structure
@@ -249,11 +249,24 @@ cd /YOUR_INSTALL_DIR
│ ├── down.sh # Stop all services
│ ├── restart.sh # Restart all services
│ └── compose files...
├── setup.sh # Installation script
├── recyclarr.yml # TRaSH Guide configuration
├── recyclarr-sync.sh # Manual profile update script
├── arrs-mount-healthcheck.sh
└── plex-mount-healthcheck.sh
├── setup/ # Setup scripts and libraries
│ ├── lib/ # Modular function libraries
│ └── utils/ # Setup utilities
├── scripts/ # Maintenance scripts
│ ├── health/ # Health check scripts
│ │ ├── arrs-mount-healthcheck.sh
│ │ └── plex-mount-healthcheck.sh
│ ├── maintenance/ # Backup scripts
│ └── recyclarr-sync.sh
├── config/ # Configuration templates
│ ├── recyclarr.yml
│ ├── rclone.conf
│ ├── indexers/
│ └── autoscan/
├── setup.sh # Main installation script
├── README.md
├── INSTALLATION.md
└── LICENSE
```
## Troubleshooting
@@ -365,8 +378,8 @@ crontab -l | grep healthcheck
**Manually run health checks:**
```bash
/YOUR_INSTALL_DIR/plex-mount-healthcheck.sh
/YOUR_INSTALL_DIR/arrs-mount-healthcheck.sh
/YOUR_INSTALL_DIR/scripts/health/plex-mount-healthcheck.sh
/YOUR_INSTALL_DIR/scripts/health/arrs-mount-healthcheck.sh
```
### Update Containers

View File

@@ -1,5 +0,0 @@
[zurg]
type = webdav
url = http://zurg:9999/dav
vendor = other
pacer_min_sleep = 0

View File

@@ -1,359 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/recyclarr/recyclarr/master/schemas/config-schema.json
# Recyclarr Configuration
# https://recyclarr.dev/wiki/
# Radarr - Movies
radarr:
movies:
base_url: http://radarr:7878
api_key:
include:
- template: radarr-quality-definition-movie
quality_profiles:
- name: Recyclarr-1080p
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Remux-1080p
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Remux-1080p
enabled: true
- name: Bluray-1080p
enabled: true
- name: WEB 1080p
qualities:
- WEBRip-1080p
- WEBDL-1080p
enabled: true
- name: HDTV-1080p
enabled: true
- name: Recyclarr-2160p
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Remux-2160p
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Remux-2160p
enabled: true
- name: Bluray-2160p
enabled: true
- name: WEB 2160p
qualities:
- WEBRip-2160p
- WEBDL-2160p
enabled: true
- name: HDTV-2160p
enabled: true
- name: Recyclarr-Any
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Remux-2160p
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Remux-2160p
enabled: true
- name: Bluray-2160p
enabled: true
- name: WEB 2160p
qualities:
- WEBRip-2160p
- WEBDL-2160p
enabled: true
- name: HDTV-2160p
enabled: true
- name: Remux-1080p
enabled: true
- name: Bluray-1080p
enabled: true
- name: WEB 1080p
qualities:
- WEBRip-1080p
- WEBDL-1080p
enabled: true
- name: HDTV-1080p
enabled: true
delete_old_custom_formats: false
replace_existing_custom_formats: false
custom_formats:
- trash_ids:
# Audio
- 496f355514737f7d83bf7aa4d24f8169 # TrueHD ATMOS
- 2f22d89048b01681dde8afe203bf2e95 # DTS X
- 417804f7f2c4308c1f4c5d380d4c4475 # ATMOS (undefined)
- 1af239278386be2919e1bcee0bde047e # DD+ Atmos
- 3cafb66171b47f226146a0770576870f # TrueHD
- dcf3ec6938fa32445f590a4da84256cd # DTS-HD-MA
- a570d4a0e56a2874b64e5bfa55202a1b # FLAC
- e7c2fcae07cbada050a0af3357491d7b # PCM
- 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD-HRA
- 185f1dd7264c4562b9022d963ac37424 # DD+
- f9f847ac70a0af62ea4a08280b859636 # DTS-ES
- 1c1a4c5e823891c75bc50380a6866f73 # DTS
- 240770601cc226190c367ef59aba7463 # AAC
- c2998bd0d90ed5621d8df281e839436e # DD
# Movie Versions
- 0f12c086e289cf966fa5948eac571f44 # Hybrid
- 570bc9ebecd92723d2d21500f4be314c # Remaster
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
- e0c07d59beb37348e975a930d5e50319 # Criterion Collection
- 9d27d9d2181838f76dee150882bdc58c # Masters of Cinema
- db9b4c4b53d312a3ca5f1378f6440fc9 # Vinegar Syndrome
- 957d0f44b592285f26449575e8b1167e # Special Edition
- eecf3a857724171f968a66cb5719e152 # IMAX
- 9f6cbff8cfe4ebbc1bde14c7b7bec0de # IMAX Enhanced
# Unwanted
- ed38b889b31be83fda192888e2286d83 # BR-DISK
- 90a6f9a284dff5103f6346090e6280c8 # LQ
- e204b80c87be9497a8a6eaff48f72905 # LQ (Release Title)
- dc98083864ea246d05a42df0d05f81cc # x265 (HD)
- b8cd450cbfa689c0259a01d9e29ba3d6 # 3D
- 0a3f082873eb454bde444150b70253cc # Extras
- cae4ca30163749b891686f95532519bd # AV1
# Common HQ Release Groups
- c20f169ef63c5f40c2def54abaf4438e # WEB Tier 01
- 403816d65392c79236dcb6dd591aeda4 # WEB Tier 02
- af94e0fe497124d1f9ce732069ec8c3b # WEB Tier 03
# Misc
- e7718d7a3ce595f289bfee26adc178f5 # Repack/Proper
- ae43b294509409a6a13919dedd4764c4 # Repack2
- 5caaaa1c08c1742aa4342d8c4cc463f2 # Repack3
# Streaming Services
- b3b3a6ac74ecbd56bcdbefa4799fb9df # AMZN
- 40e9380490e748672c2522eaaeb692f7 # ATVP
- cc5e51a9e85a6296ceefe097a77f12f4 # BCORE
- 16622a6911d1ab5d5b8b713d5b0036d4 # CRiT
- 84272245b2988854bfb76a16e60baea5 # DSNP
- 509e5f41146e278f9eab1ddaceb34515 # HBO
- 5763d1b0ce84aff3b21038eea8e9b8ad # HMAX
- 526d445d4c16214309f0fd2b3be18a89 # Hulu
- e0ec9672be6cac914ffad34a6b077209 # iT
- 6a061313d22e51e0f25b7cd4dc065233 # MAX
- 2a6039655313bf5dab1e43523b62c374 # MA
- 170b1d363bd8516fbf3a3eb05d4faff6 # NF
- e36a0ba1bc902b26ee40818a1d59b8bd # PMTP
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
- c2863d2a50c9acad1fb50e53ece60817 # STAN
assign_scores_to:
- name: Recyclarr-1080p
- name: Recyclarr-2160p
- trash_ids:
# 1080p HQ Release Groups
- ed27ebfef2f323e964fb1f61391bcb35 # HD Bluray Tier 01
- c20c8647f2746a1f4c4262b0fbbeeeae # HD Bluray Tier 02
- 5608c71bcebba0a5e666223bae8c9227 # HD Bluray Tier 03
assign_scores_to:
- name: Recyclarr-1080p
- trash_ids:
# 2160p HQ Release Groups
- 4d74ac4c4db0b64bff6ce0cffef99bf0 # UHD Bluray Tier 01
- a58f517a70193f8e578056642178419d # UHD Bluray Tier 02
- e71939fae578037e7aed3ee219bbe7c1 # UHD Bluray Tier 03
assign_scores_to:
- name: Recyclarr-2160p
- trash_ids:
# HDR Formats
- e23edd2482476e595fb990b12e7c609c # DV HDR10
- 58d6a88f13e2db7f5059c41047876f00 # DV
- 55d53828b9d81cbe20b02efd00aa0efd # DV HLG
- a3e19f8f627608af0211acd02bf89735 # DV SDR
- dfb86d5941bc9075d6af23b09c2aeecd # HDR10
- e61e28db95d22bedcadf030b8f156d96 # HDR
- 2a4d9069cc1fe3242ff9bdaebed239bb # HDR (undefined)
- 08d6d8834ad9ec87b1dc7ec8148e7a1f # PQ
- 9364dd386c9b4a1100dde8264690add7 # HLG
- 9c38ebb7384dada637be8899efa68e6f # SDR
assign_scores_to:
- name: Recyclarr-2160p
# Media naming using Plex conventions with TMDB
media_naming:
folder: plex-tmdb
movie:
rename: true
standard: plex-tmdb
# Sonarr - TV Series
sonarr:
series:
base_url: http://sonarr:8989
api_key:
include:
- template: sonarr-quality-definition-series
quality_profiles:
- name: Recyclarr-1080p
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Bluray-1080p Remux
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Bluray-1080p Remux
enabled: true
- name: Bluray-1080p
enabled: true
- name: WEB 1080p
qualities:
- WEBRip-1080p
- WEBDL-1080p
enabled: true
- name: HDTV-1080p
enabled: true
- name: Recyclarr-2160p
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Bluray-2160p Remux
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Bluray-2160p Remux
enabled: true
- name: Bluray-2160p
enabled: true
- name: WEB 2160p
qualities:
- WEBRip-2160p
- WEBDL-2160p
enabled: true
- name: HDTV-2160p
enabled: true
- name: Recyclarr-Any
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Bluray-2160p Remux
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Bluray-2160p Remux
enabled: true
- name: Bluray-2160p
enabled: true
- name: WEB 2160p
qualities:
- WEBRip-2160p
- WEBDL-2160p
enabled: true
- name: HDTV-2160p
enabled: true
- name: Bluray-1080p Remux
enabled: true
- name: Bluray-1080p
enabled: true
- name: WEB 1080p
qualities:
- WEBRip-1080p
- WEBDL-1080p
enabled: true
- name: HDTV-1080p
enabled: true
delete_old_custom_formats: false
replace_existing_custom_formats: false
custom_formats:
- trash_ids:
# Unwanted
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
- e2315f990da2e2cbfc9fa5b7a6fcfe48 # LQ (Release Title)
- 47435ece6b99a0b477caf360e79ba0bb # x265 (HD)
- fbcb31d8dabd2a319072b84fc0b180c8 # Extras
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
# Misc
- ec8fa7296b64e8cd390a1600981f3923 # Repack/Proper
- eb3d5cc0a2be0db205fb823640db6a3c # Repack v2
- 44e7c4de10ae50265753082e5dc76047 # Repack v3
# Streaming Services
- d660701077794679fd59e8bdf4ce3a29 # AMZN
- f67c9ca88f463a48346062e8ad07713f # ATVP
- 77a7b25585c18af08f60b1547bb9b4fb # CC
- 36b72f59f4ea20aad9316f475f2d9fbb # DCU
- 89358767a60cc28783cdc3d0be9388a4 # DSNP
- a880d6abc21e7c16884f3ae393f84179 # HMAX
- 7a235133c87f7da4c8cccceca7e3c7a6 # HBO
- f6cce30f1733d5c8194222a7507909bb # Hulu
- 0ac24a2a68a9700bcb7eeca8e5cd644c # iT
- 81d1fbf600e2540cee87f3a23f9d3c1c # MAX
- d34870697c9db575f17700212167be23 # NF
- c67a75ae4a1715f2bb4d492755ba4195 # PMTP
- 1656adc6d7bb2c8cca6acfb6592db421 # PCOK
- ae58039e1319178e6be73caab5c42166 # SHO
- 1efe8da11bfd74fbbcd4d8117ddb9213 # STAN
- 9623c5c9cac8e939c1b9aedd32f640bf # SYFY
# HQ Source Groups
- e6258996055b9fbab7e9cb2f75819294 # WEB Tier 01
- 58790d4e2fdcd9733aa7ae68ba2bb503 # WEB Tier 02
- d84935abd3f8556dcd51d4f27e22d0a6 # WEB Tier 03
- d0c516558625b04b363fa6c5c2c7cfd4 # WEB Scene
assign_scores_to:
- name: Recyclarr-1080p
- name: Recyclarr-2160p
- trash_ids:
# HDR Formats
- 7878c33f1963fefb3d6c8657d46c2f0a # DV HDR10
- 6d0d8de7b57e35518ac0308b0ddf404e # DV
- 1f733af03141f068a540eec352589a89 # DV HLG
- 27954b0a80aab882522a88a4d9eae1cd # DV SDR
- 3497799d29a085e2ac2df9d468413c94 # HDR10
- 3e2c4e748b64a1a1118e0ea3f4cf6875 # HDR
- bb019e1cd00f304f80971c965de064dc # HDR (undefined)
- 2a7e3be05d3861d6df7171ec74cad727 # PQ
- 17e889ce13117940092308f48b48b45b # HLG
- 2016d1676f5ee13a5b7257ff86ac9a93 # SDR
# UHD Streaming
- 43b3cf48cb385cd3eac608ee6bca7f09 # UHD Streaming Boost
- d2d299244a92b8a52d4921ce3897a256 # UHD Streaming Cut
assign_scores_to:
- name: Recyclarr-2160p
# Media naming using Plex conventions with TVDB
media_naming:
series: plex-tvdb
season: default
episodes:
rename: true
standard: default
daily: default
anime: default

View File

@@ -0,0 +1,251 @@
#!/bin/bash
# MediaCenter Configuration Backup Script - OPTIMIZED VERSION
# Backs up essential configuration only, excludes logs and large databases
set -e
BACKUP_DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_NAME="mediacenter-backup-${BACKUP_DATE}"
BACKUP_DIR="/tmp/${BACKUP_NAME}"
MEDIACENTER_ROOT="/mediacenter"
MOUNT_ROOT="/mnt/mediacenter"
echo "🚀 Starting OPTIMIZED MediaCenter backup: ${BACKUP_NAME}"
# Create backup directory
mkdir -p "${BACKUP_DIR}"
chmod 755 "${BACKUP_DIR}"
echo "📁 Creating backup structure..."
# 1. Backup Docker Compose files and environment
echo " → Docker configuration"
cp "${MEDIACENTER_ROOT}/docker/docker-compose.yml" "${BACKUP_DIR}/"
cp "${MEDIACENTER_ROOT}/docker/.env.defaults" "${BACKUP_DIR}/"
cp "${MEDIACENTER_ROOT}/docker/.env.local" "${BACKUP_DIR}/"
cp "${MEDIACENTER_ROOT}/docker/up.sh" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ up.sh not found"
cp "${MEDIACENTER_ROOT}/docker/down.sh" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ down.sh not found"
cp -r "${MEDIACENTER_ROOT}/docker/compose-services/" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ compose-services not found"
cp "${MOUNT_ROOT}/setup.sh" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ setup.sh not found"
cp "${MOUNT_ROOT}/zurg.yml" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ zurg.yml not found"
cp "${MOUNT_ROOT}/CLAUDE.md" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ CLAUDE.md not found"
cp "${MOUNT_ROOT}/backup-mediacenter.sh" "${BACKUP_DIR}/" 2>/dev/null || true
cp "/tmp/mediacenter-permissions-report.txt" "${BACKUP_DIR}/" 2>/dev/null || true
# 2. Backup service configurations (OPTIMIZED - exclude large files)
echo " → Service configurations (optimized)"
mkdir -p "${BACKUP_DIR}/config"
for service_dir in ${MEDIACENTER_ROOT}/config/*/; do
service_name=$(basename "$service_dir")
echo " - ${service_name}"
# Create service directory
mkdir -p "${BACKUP_DIR}/config/${service_name}"
# Copy config files but exclude large databases and logs
sudo rsync -av \
--exclude='*.log' \
--exclude='*.log.*' \
--exclude='logs.db*' \
--exclude='*.db-wal' \
--exclude='*.db-shm' \
--exclude='title.basics.tsv' \
--exclude='trakt_cache.sqlite' \
--exclude='MediaCover/' \
--exclude='asp/*.xml' \
--exclude='Definitions/' \
--exclude='cache/' \
--exclude='repositories/' \
--exclude='extras/' \
--exclude='metadata/' \
--exclude='database.db/' \
--exclude='redis/' \
--exclude='Library/Application Support/Plex Media Server/Cache/' \
--exclude='Library/Application Support/Plex Media Server/Metadata/' \
--exclude='Library/Application Support/Plex Media Server/Media/' \
--exclude='access.log' \
"${service_dir}" "${BACKUP_DIR}/config/${service_name}/" 2>/dev/null || true
done
# 3. Create essential config files list for reference
echo " → Creating config inventory"
cat > "${BACKUP_DIR}/essential-configs.txt" << 'EOF'
Essential Configuration Files Backed Up:
=========================================
- docker-compose.yml (Docker stack definition)
- .env.defaults (Standard configuration)
- .env.local (Environment-specific secrets)
- compose-services/ (Individual service files)
- up.sh/down.sh (Convenience scripts)
- zurg.yml (Real-Debrid configuration)
- */config.xml (Service configurations)
- */settings.json (Service settings)
- recyclarr.yml (Quality profiles)
- autoscan/config.yml (Webhook configuration)
- traefik/tls.yml (TLS configuration)
Files NOT included (can be regenerated):
=========================================
- *.log files (Will be recreated)
- logs.db files (Will be recreated)
- MediaCover directories (Will be re-downloaded)
- Cache directories (Will be rebuilt)
- title.basics.tsv (Can be re-downloaded)
- trakt_cache.sqlite (Will be rebuilt on sync)
EOF
# 4. Create media structure (empty directories)
echo " → Media directory structure (empty)"
mkdir -p "${BACKUP_DIR}/data/media/movies"
mkdir -p "${BACKUP_DIR}/data/media/tv"
mkdir -p "${BACKUP_DIR}/data/media/youtube"
mkdir -p "${BACKUP_DIR}/data/realdebrid-zurg"
mkdir -p "${BACKUP_DIR}/data/symlinks/radarr"
mkdir -p "${BACKUP_DIR}/data/symlinks/sonarr"
touch "${BACKUP_DIR}/data/media/.gitkeep"
touch "${BACKUP_DIR}/data/realdebrid-zurg/.gitkeep"
# 5. Backup system user configuration info
echo " → System users information"
getent group mediacenter > "${BACKUP_DIR}/mediacenter-group.txt" 2>/dev/null || echo "Group mediacenter not found" > "${BACKUP_DIR}/mediacenter-group.txt"
getent passwd | grep -E '^(rclone|sonarr|radarr|prowlarr|overseerr|plex|recyclarr|rdtclient|autoscan|traefik|pinchflat|plextraktsync|homarr|dashdot):' > "${BACKUP_DIR}/mediacenter-users.txt" 2>/dev/null || echo "No mediacenter users found" > "${BACKUP_DIR}/mediacenter-users.txt"
# 6. Docker images list
echo " → Docker images list"
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}\t{{.Size}}" | grep -E "(mediacenter|traefik|plex|overseerr|prowlarr|sonarr|radarr|zurg|zilean|rclone|autoscan|homarr|dashdot|recyclarr|rdtclient|pinchflat|plextraktsync|watchtower|postgres)" > "${BACKUP_DIR}/docker-images.txt" 2>/dev/null || echo "No mediacenter images found" > "${BACKUP_DIR}/docker-images.txt"
# 7. Create restore instructions
cat > "${BACKUP_DIR}/RESTORE-INSTRUCTIONS.md" << 'EOF'
# MediaCenter Restore Instructions - OPTIMIZED BACKUP
## Important Note
This is an OPTIMIZED backup that excludes logs, caches, and large databases.
These will be regenerated automatically when services start.
## Prerequisites
- Ubuntu Server with Docker and Docker Compose installed
- Static IP configuration
- Active Real-Debrid subscription
## Restore Steps
1. **Stop any existing MediaCenter services:**
```bash
docker compose down
```
2. **Restore files:**
```bash
# Copy configuration files
sudo cp -r config/ /mediacenter/
sudo mkdir -p /mediacenter/docker/
sudo cp docker-compose.yml .env.defaults .env.local up.sh down.sh /mediacenter/docker/
sudo cp -r compose-services/ /mediacenter/docker/
sudo cp setup.sh zurg.yml CLAUDE.md /mnt/mediacenter/
# Restore directory structure
sudo mkdir -p /mediacenter/data/{media/{movies,tv,youtube},realdebrid-zurg,symlinks/{radarr,sonarr}}
```
3. **Recreate system users:**
```bash
# Create mediacenter group
sudo groupadd -g 13000 mediacenter
# Create users (check mediacenter-users.txt for full list)
sudo useradd -u 13001 -g 13000 -M -s /sbin/nologin rclone
sudo useradd -u 13002 -g 13000 -M -s /sbin/nologin sonarr
sudo useradd -u 13003 -g 13000 -M -s /sbin/nologin radarr
# ... (continue with all users from mediacenter-users.txt)
```
4. **Set permissions (use mediacenter-permissions-report.txt for exact commands):**
```bash
sudo chown -R 13000:13000 /mediacenter/
sudo chmod -R 775 /mediacenter/config/
```
5. **Update configuration:**
- Edit `.env` with your timezone and Plex claim token
- Edit `zurg.yml` with your Real-Debrid API key
- Update any service-specific configurations as needed
6. **Download missing files (if needed):**
- Zilean: title.basics.tsv will be downloaded on first run
- MediaCover: Will be re-downloaded as media is added
7. **Start services:**
```bash
cd /mediacenter/docker/
./up.sh
```
8. **Verify all services are healthy:**
```bash
docker compose ps
```
## Files NOT included in this backup:
- Log files (*.log)
- Large databases (logs.db, trakt_cache.sqlite)
- Media cover images
- Cache directories
- title.basics.tsv (1GB file)
These will be automatically recreated when services start.
EOF
# 8. Create backup metadata
cat > "${BACKUP_DIR}/backup-info.txt" << EOF
MediaCenter OPTIMIZED Backup Information
=========================================
Backup Date: $(date)
Backup Name: ${BACKUP_NAME}
Source Path: ${MEDIACENTER_ROOT}
Mount Path: ${MOUNT_ROOT}
System: $(uname -a)
Backup Type: OPTIMIZED (excludes logs, caches, large DBs)
Services Included:
- All 19 services configurations
- Docker Compose stack
- Environment variables
- User/group information
- Directory structure
Excluded from backup:
- Log files
- Large databases
- Cache directories
- Media cover images
- title.basics.tsv
Total Config Size: $(du -sh "${BACKUP_DIR}/config" 2>/dev/null | cut -f1 || echo "N/A")
EOF
# 9. Create compressed archive
echo "📦 Creating compressed backup..."
cd /tmp
tar -czf "${BACKUP_NAME}.tar.gz" "${BACKUP_NAME}"
BACKUP_SIZE=$(du -sh "${BACKUP_NAME}.tar.gz" | cut -f1)
echo "✅ OPTIMIZED Backup completed successfully!"
echo ""
echo "📊 Backup Details:"
echo " Name: ${BACKUP_NAME}.tar.gz"
echo " Size: ${BACKUP_SIZE}"
echo " Path: /tmp/${BACKUP_NAME}.tar.gz"
echo ""
echo "💡 This optimized backup excludes:"
echo " - Log files (will be recreated)"
echo " - Large databases (will be rebuilt)"
echo " - Cache directories (will be regenerated)"
echo ""
echo "🔍 To extract: tar -xzf ${BACKUP_NAME}.tar.gz"
echo "📋 See RESTORE-INSTRUCTIONS.md for restore steps"
echo "📑 See mediacenter-permissions-report.txt for exact permissions"
# Cleanup temporary directory
rm -rf "${BACKUP_DIR}"

View File

@@ -0,0 +1,183 @@
#!/bin/bash
# MediaCenter Configuration Backup Script
# Backs up all configuration except media files
set -e
BACKUP_DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_NAME="mediacenter-backup-${BACKUP_DATE}"
BACKUP_DIR="/tmp/${BACKUP_NAME}"
MEDIACENTER_ROOT="/mediacenter"
MOUNT_ROOT="/mnt/mediacenter"
echo "🚀 Starting MediaCenter backup: ${BACKUP_NAME}"
# Create backup directory
mkdir -p "${BACKUP_DIR}"
chmod 755 "${BACKUP_DIR}"
echo "📁 Creating backup structure..."
# 1. Backup Docker Compose files and environment
echo " → Docker configuration"
cp "${MOUNT_ROOT}/compose.yml" "${BACKUP_DIR}/"
cp "${MOUNT_ROOT}/.env" "${BACKUP_DIR}/"
cp "${MOUNT_ROOT}/setup.sh" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ setup.sh not found"
cp "${MOUNT_ROOT}/zurg.yml" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ zurg.yml not found"
cp "${MOUNT_ROOT}/CLAUDE.md" "${BACKUP_DIR}/" 2>/dev/null || echo " ⚠️ CLAUDE.md not found"
# 2. Backup all service configurations
echo " → Service configurations"
if [ -d "${MEDIACENTER_ROOT}/config" ]; then
# Use sudo to handle permission issues and exclude problematic files
sudo cp -r "${MEDIACENTER_ROOT}/config" "${BACKUP_DIR}/" 2>/dev/null || true
# Skip asp files that cause permission issues
sudo find "${BACKUP_DIR}/config" -path "*/asp/*.xml" -delete 2>/dev/null || true
else
echo " ⚠️ Config directory not found at ${MEDIACENTER_ROOT}/config"
fi
# 3. Create media structure (empty directories)
echo " → Media directory structure (empty)"
mkdir -p "${BACKUP_DIR}/data/media/movies"
mkdir -p "${BACKUP_DIR}/data/media/tv"
mkdir -p "${BACKUP_DIR}/data/media/youtube"
mkdir -p "${BACKUP_DIR}/data/realdebrid-zurg"
mkdir -p "${BACKUP_DIR}/data/symlinks/radarr"
mkdir -p "${BACKUP_DIR}/data/symlinks/sonarr"
# 4. Create empty .gitkeep files to preserve structure
touch "${BACKUP_DIR}/data/media/.gitkeep"
touch "${BACKUP_DIR}/data/realdebrid-zurg/.gitkeep"
# 5. Backup system user configuration info
echo " → System users information"
getent group mediacenter > "${BACKUP_DIR}/mediacenter-group.txt" 2>/dev/null || echo "Group mediacenter not found" > "${BACKUP_DIR}/mediacenter-group.txt"
getent passwd | grep -E '^(rclone|sonarr|radarr|prowlarr|overseerr|plex|recyclarr|rdtclient|autoscan|traefik|pinchflat|plextraktsync|homarr|dashdot):' > "${BACKUP_DIR}/mediacenter-users.txt" 2>/dev/null || echo "No mediacenter users found" > "${BACKUP_DIR}/mediacenter-users.txt"
# 6. Docker images list
echo " → Docker images list"
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}\t{{.Size}}" | grep -E "(mediacenter|traefik|plex|overseerr|prowlarr|sonarr|radarr|zurg|zilean|rclone|autoscan|homarr|dashdot|recyclarr|rdtclient|pinchflat|plextraktsync|watchtower|postgres)" > "${BACKUP_DIR}/docker-images.txt" 2>/dev/null || echo "No mediacenter images found" > "${BACKUP_DIR}/docker-images.txt"
# 7. Create restore instructions
cat > "${BACKUP_DIR}/RESTORE-INSTRUCTIONS.md" << 'EOF'
# MediaCenter Restore Instructions
## Prerequisites
- Ubuntu Server with Docker and Docker Compose installed
- Static IP configuration
- Active Real-Debrid subscription
## Restore Steps
1. **Stop any existing MediaCenter services:**
```bash
docker compose down
```
2. **Restore files:**
```bash
# Copy configuration files
sudo cp -r config/ /mediacenter/
sudo cp compose.yml .env setup.sh zurg.yml CLAUDE.md /mnt/mediacenter/
# Restore directory structure
sudo mkdir -p /mediacenter/data/{media/{movies,tv,youtube},realdebrid-zurg,symlinks/{radarr,sonarr}}
```
3. **Recreate system users:**
```bash
# Create mediacenter group
sudo groupadd -g 13000 mediacenter
# Create users (check mediacenter-users.txt for full list)
sudo useradd -u 13001 -g 13000 -M -s /sbin/nologin rclone
sudo useradd -u 13002 -g 13000 -M -s /sbin/nologin sonarr
sudo useradd -u 13003 -g 13000 -M -s /sbin/nologin radarr
# ... (continue with all users from mediacenter-users.txt)
```
4. **Set permissions:**
```bash
sudo chown -R 13000:13000 /mediacenter/
sudo chmod -R 775 /mediacenter/config/
```
5. **Update configuration:**
- Edit `.env` with your timezone and Plex claim token
- Edit `zurg.yml` with your Real-Debrid API key
- Update any service-specific configurations as needed
6. **Start services:**
```bash
docker compose up -d
```
7. **Verify all services are healthy:**
```bash
docker compose ps
```
## Important Notes
- Media files are NOT included in this backup
- Update Plex claim token (valid for 4 minutes only)
- Verify Real-Debrid API key in zurg.yml
- Check service-specific configurations for any hardcoded paths or keys
## Service Access
- Homarr Dashboard: http://home.medianita
- Overseerr: http://overseerr.medianita
- Plex: Network host mode
- Other services: Check compose.yml for ports and domains
EOF
# 8. Create backup metadata
cat > "${BACKUP_DIR}/backup-info.txt" << EOF
MediaCenter Backup Information
=============================
Backup Date: $(date)
Backup Name: ${BACKUP_NAME}
Source Path: ${MEDIACENTER_ROOT}
Mount Path: ${MOUNT_ROOT}
System: $(uname -a)
Services Included:
- Plex Media Server
- Overseerr (Request Management)
- Prowlarr (Indexer Management)
- Radarr (Movie Management)
- Sonarr (TV Management)
- RDTClient (Download Client)
- Zurg (Real-Debrid WebDAV)
- Zilean (Torrent Indexer)
- Recyclarr (Quality Profiles)
- Autoscan (Library Updates)
- Traefik (Reverse Proxy)
- Homarr (Dashboard)
- DashDot (System Monitor)
- Pinchflat (YouTube Downloader)
- PlexTraktSync (Trakt Integration)
- Watchtower (Auto Updates)
Total Config Size: $(du -sh "${BACKUP_DIR}/config" 2>/dev/null | cut -f1 || echo "N/A")
EOF
# 9. Create compressed archive
echo "📦 Creating compressed backup..."
cd /tmp
tar -czf "${BACKUP_NAME}.tar.gz" "${BACKUP_NAME}"
BACKUP_SIZE=$(du -sh "${BACKUP_NAME}.tar.gz" | cut -f1)
echo "✅ Backup completed successfully!"
echo ""
echo "📊 Backup Details:"
echo " Name: ${BACKUP_NAME}.tar.gz"
echo " Size: ${BACKUP_SIZE}"
echo " Path: /tmp/${BACKUP_NAME}.tar.gz"
echo ""
echo "🔍 To extract: tar -xzf ${BACKUP_NAME}.tar.gz"
echo "📋 See RESTORE-INSTRUCTIONS.md for restore steps"
# Cleanup temporary directory
rm -rf "${BACKUP_DIR}"

View File

@@ -42,7 +42,7 @@ echo ""
# Run Recyclarr with Docker
docker run --rm \
--network mediacenter \
-v "${SCRIPT_DIR}/recyclarr.yml:/config/recyclarr.yml:ro" \
-v "${SCRIPT_DIR}/../config/recyclarr.yml:/config/recyclarr.yml:ro" \
-e RADARR_API_KEY="${RADARR_API_KEY}" \
-e SONARR_API_KEY="${SONARR_API_KEY}" \
ghcr.io/recyclarr/recyclarr:latest \

View File

@@ -440,13 +440,13 @@ if [ "$ROOT_DIR" != "$SCRIPT_DIR" ]; then
echo "✓ Docker configuration copied to ${ROOT_DIR}/docker"
# Copy rclone.conf
sudo cp "$SCRIPT_DIR/rclone.conf" "${ROOT_DIR}/"
sudo cp "$SCRIPT_DIR/config/rclone.conf" "${ROOT_DIR}/"
sudo chown rclone:mediacenter "${ROOT_DIR}/rclone.conf"
echo "✓ rclone.conf copied to ${ROOT_DIR}/"
# Copy recyclarr configuration
sudo cp "$SCRIPT_DIR/recyclarr.yml" "${ROOT_DIR}/"
sudo cp "$SCRIPT_DIR/recyclarr-sync.sh" "${ROOT_DIR}/"
sudo cp "$SCRIPT_DIR/config/recyclarr.yml" "${ROOT_DIR}/"
sudo cp "$SCRIPT_DIR/scripts/recyclarr-sync.sh" "${ROOT_DIR}/"
sudo chown $INSTALL_UID:mediacenter "${ROOT_DIR}/recyclarr.yml" "${ROOT_DIR}/recyclarr-sync.sh"
sudo chmod +x "${ROOT_DIR}/recyclarr-sync.sh"
echo "✓ Recyclarr configuration copied to ${ROOT_DIR}/"
@@ -611,8 +611,8 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Installing mount healthcheck scripts..."
# Copy healthcheck scripts to /usr/local/bin/
sudo cp "$SCRIPT_DIR/arrs-mount-healthcheck.sh" /usr/local/bin/
sudo cp "$SCRIPT_DIR/plex-mount-healthcheck.sh" /usr/local/bin/
sudo cp "$SCRIPT_DIR/scripts/health/arrs-mount-healthcheck.sh" /usr/local/bin/
sudo cp "$SCRIPT_DIR/scripts/health/plex-mount-healthcheck.sh" /usr/local/bin/
# Set permissions
sudo chmod 775 /usr/local/bin/arrs-mount-healthcheck.sh

88
setup/utils/split-compose.py Executable file
View File

@@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""
Split the monolithic docker-compose.yml into individual service files
"""
import yaml
import os
from pathlib import Path
# Read the original compose file
with open('/mnt/mediacenter/compose-monolithic.yml.backup', 'r') as f:
compose_data = yaml.safe_load(f)
# Output directory
output_dir = Path('/mnt/mediacenter/compose-services')
output_dir.mkdir(exist_ok=True)
# Services to extract
services_to_extract = {
'overseerr': 'overseerr.yml',
'prowlarr': 'prowlarr.yml',
'radarr': 'radarr.yml',
'sonarr': 'sonarr.yml',
'recyclarr': 'recyclarr.yml',
'rdtclient': 'rdtclient.yml',
'zurg': 'zurg.yml',
'rclone': 'rclone.yml',
'watchtower': 'watchtower.yml',
'autoscan': 'autoscan.yml',
'zilean': 'zilean.yml',
'zilean-postgres': 'zilean-postgres.yml',
'pinchflat': 'pinchflat.yml',
'plextraktsync': 'plextraktsync.yml',
'homarr': 'homarr.yml',
'dashdot': 'dashdot.yml'
}
# Template for each service file
template = """# {service_description}
name: mediacenter
{service_yaml}"""
# Extract and save each service
for service_name, filename in services_to_extract.items():
if service_name in compose_data.get('services', {}):
service_data = compose_data['services'][service_name]
# Create service description
descriptions = {
'overseerr': 'Overseerr - Request Management',
'prowlarr': 'Prowlarr - Indexer Management',
'radarr': 'Radarr - Movie Management',
'sonarr': 'Sonarr - TV Show Management',
'recyclarr': 'Recyclarr - Quality Profiles Sync',
'rdtclient': 'RDTClient - Real-Debrid Download Client',
'zurg': 'Zurg - Real-Debrid WebDAV',
'rclone': 'Rclone - Mount Real-Debrid Storage',
'watchtower': 'Watchtower - Automatic Container Updates',
'autoscan': 'Autoscan - Plex Library Updates',
'zilean': 'Zilean - Torrent Indexer',
'zilean-postgres': 'PostgreSQL for Zilean',
'pinchflat': 'Pinchflat - YouTube Downloader',
'plextraktsync': 'PlexTraktSync - Trakt.tv Integration',
'homarr': 'Homarr - Dashboard',
'dashdot': 'DashDot - System Monitor'
}
# Convert service data to YAML
service_dict = {service_name: service_data}
service_yaml_dict = {'services': service_dict}
service_yaml = yaml.dump(service_yaml_dict,
default_flow_style=False,
sort_keys=False)
# Write to file
output_file = output_dir / filename
with open(output_file, 'w') as f:
f.write(template.format(
service_description=descriptions.get(service_name, service_name),
service_yaml=service_yaml
))
print(f"Created: {filename}")
print("\nAll services have been split into individual files!")
print("You can now use: docker compose up -d")
print("Or for specific services: docker compose up -d plex overseerr")