#!/bin/bash # ============================================================================ # Phase 2 Batch 2 Migration Script # Target: replicant (.80) # Services: tinymediamanager, autoscan, channeltube, dispatcharr # Run this on the control server (CT 127) # ============================================================================ set -e COMPOSE_BASE=~/clustered-fucks/compose-files/replicant PLAYBOOK_DIR=~/clustered-fucks/playbooks echo "╔════════════════════════════════════════════════════════════════════════════╗" echo "║ Phase 2 Batch 2: tinymediamanager, autoscan, channeltube, dispatcharr ║" echo "║ Target: replicant (192.168.1.80) ║" echo "╚════════════════════════════════════════════════════════════════════════════╝" echo "" # ============================================================================ # TINYMEDIAMANAGER # ============================================================================ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Creating: tinymediamanager" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" mkdir -p "$COMPOSE_BASE/tinymediamanager" cat > "$COMPOSE_BASE/tinymediamanager/docker-compose.yml" << 'EOF' services: tinymediamanager: image: romancin/tinymediamanager:latest-v4 container_name: tinymediamanager environment: - USER_ID=1000 - GROUP_ID=1000 - TZ=America/Indiana/Indianapolis - DISPLAY_WIDTH=1920 - DISPLAY_HEIGHT=1080 - KEEP_APP_RUNNING=1 - CLEAN_TMP_DIR=1 volumes: - ./config:/config - /volume1/Media:/media ports: - "45800:5800" # Web UI - "45900:5900" # VNC restart: unless-stopped networks: - proxy deploy: resources: limits: memory: 1G cpus: '2.0' labels: - "autoheal=true" - "com.centurylinklabs.watchtower.enable=true" networks: proxy: external: true EOF echo "✅ Created $COMPOSE_BASE/tinymediamanager/docker-compose.yml" # Ansible playbook for tinymediamanager cat > "$PLAYBOOK_DIR/deploy-tinymediamanager.yml" << 'EOF' --- - name: Deploy TinyMediaManager to replicant hosts: replicant vars: service_name: tinymediamanager service_dir: /home/maddox/docker/appdata/{{ service_name }} compose_src: "{{ playbook_dir }}/../compose-files/replicant/{{ service_name }}" tasks: - name: Create service directory ansible.builtin.file: path: "{{ service_dir }}" state: directory owner: maddox group: maddox mode: '0755' - name: Create config subdirectory ansible.builtin.file: path: "{{ service_dir }}/config" state: directory owner: maddox group: maddox mode: '0755' - name: Copy docker-compose.yml ansible.builtin.copy: src: "{{ compose_src }}/docker-compose.yml" dest: "{{ service_dir }}/docker-compose.yml" owner: maddox group: maddox mode: '0644' - name: Deploy container community.docker.docker_compose_v2: project_src: "{{ service_dir }}" state: present pull: always become: yes become_user: maddox EOF echo "✅ Created $PLAYBOOK_DIR/deploy-tinymediamanager.yml" # ============================================================================ # AUTOSCAN # ============================================================================ echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Creating: autoscan" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" mkdir -p "$COMPOSE_BASE/autoscan" cat > "$COMPOSE_BASE/autoscan/docker-compose.yml" << 'EOF' services: autoscan: image: cloudb0x/autoscan:latest container_name: autoscan environment: - PUID=1000 - PGID=1000 - TZ=America/Indiana/Indianapolis volumes: - ./config:/config - /volume1/Media:/media:ro - /volume1/Downloads:/downloads:ro ports: - "3030:3030" restart: unless-stopped networks: - proxy deploy: resources: limits: memory: 512M cpus: '1.0' healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3030/health"] interval: 30s timeout: 10s start_period: 40s retries: 3 labels: - "autoheal=true" - "com.centurylinklabs.watchtower.enable=true" networks: proxy: external: true EOF echo "✅ Created $COMPOSE_BASE/autoscan/docker-compose.yml" # Ansible playbook for autoscan cat > "$PLAYBOOK_DIR/deploy-autoscan.yml" << 'EOF' --- - name: Deploy Autoscan to replicant hosts: replicant vars: service_name: autoscan service_dir: /home/maddox/docker/appdata/{{ service_name }} compose_src: "{{ playbook_dir }}/../compose-files/replicant/{{ service_name }}" tasks: - name: Create service directory ansible.builtin.file: path: "{{ service_dir }}" state: directory owner: maddox group: maddox mode: '0755' - name: Create config subdirectory ansible.builtin.file: path: "{{ service_dir }}/config" state: directory owner: maddox group: maddox mode: '0755' - name: Copy docker-compose.yml ansible.builtin.copy: src: "{{ compose_src }}/docker-compose.yml" dest: "{{ service_dir }}/docker-compose.yml" owner: maddox group: maddox mode: '0644' - name: Deploy container community.docker.docker_compose_v2: project_src: "{{ service_dir }}" state: present pull: always become: yes become_user: maddox EOF echo "✅ Created $PLAYBOOK_DIR/deploy-autoscan.yml" # ============================================================================ # CHANNELTUBE # ============================================================================ echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Creating: channeltube" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" mkdir -p "$COMPOSE_BASE/channeltube" cat > "$COMPOSE_BASE/channeltube/docker-compose.yml" << 'EOF' services: channeltube: image: thewicklowwolf/channeltube:latest container_name: channeltube environment: - PUID=1000 - PGID=1000 - TZ=America/Indiana/Indianapolis volumes: - ./config:/channeltube/config - /volume1/Media/Youtube/movies:/channeltube/downloads - /volume1/Media/Youtube/audio:/channeltube/audio_downloads ports: - "5444:5000" restart: unless-stopped networks: - proxy deploy: resources: limits: memory: 1G cpus: '2.0' labels: - "autoheal=true" - "com.centurylinklabs.watchtower.enable=true" networks: proxy: external: true EOF echo "✅ Created $COMPOSE_BASE/channeltube/docker-compose.yml" # Ansible playbook for channeltube cat > "$PLAYBOOK_DIR/deploy-channeltube.yml" << 'EOF' --- - name: Deploy ChannelTube to replicant hosts: replicant vars: service_name: channeltube service_dir: /home/maddox/docker/appdata/{{ service_name }} compose_src: "{{ playbook_dir }}/../compose-files/replicant/{{ service_name }}" tasks: - name: Create service directory ansible.builtin.file: path: "{{ service_dir }}" state: directory owner: maddox group: maddox mode: '0755' - name: Create config subdirectory ansible.builtin.file: path: "{{ service_dir }}/config" state: directory owner: maddox group: maddox mode: '0755' - name: Copy docker-compose.yml ansible.builtin.copy: src: "{{ compose_src }}/docker-compose.yml" dest: "{{ service_dir }}/docker-compose.yml" owner: maddox group: maddox mode: '0644' - name: Deploy container community.docker.docker_compose_v2: project_src: "{{ service_dir }}" state: present pull: always become: yes become_user: maddox EOF echo "✅ Created $PLAYBOOK_DIR/deploy-channeltube.yml" # ============================================================================ # DISPATCHARR (with proxy to gluetun VPN) # ============================================================================ echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Creating: dispatcharr (using gluetun proxy for VPN)" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" mkdir -p "$COMPOSE_BASE/dispatcharr" cat > "$COMPOSE_BASE/dispatcharr/docker-compose.yml" << 'EOF' services: dispatcharr: image: ghcr.io/dispatcharr/dispatcharr:latest container_name: dispatcharr environment: - PUID=1000 - PGID=1000 - TZ=America/Indiana/Indianapolis - PORT=9191 # Route traffic through gluetun's HTTP proxy on download-stack - HTTP_PROXY=http://192.168.1.122:38888 - HTTPS_PROXY=http://192.168.1.122:38888 - http_proxy=http://192.168.1.122:38888 - https_proxy=http://192.168.1.122:38888 # GPU settings (for future pve-alien, or CPU fallback) - NVIDIA_VISIBLE_DEVICES=all - NVIDIA_DRIVER_CAPABILITIES=compute,video,utility volumes: - ./data:/data ports: - "9191:9191" restart: unless-stopped networks: - proxy # Intel QuickSync access (pve-z620 has limited decode capability) devices: - /dev/dri:/dev/dri group_add: - video - render deploy: resources: limits: memory: 2G cpus: '2.0' labels: - "autoheal=true" - "com.centurylinklabs.watchtower.enable=true" networks: proxy: external: true EOF echo "✅ Created $COMPOSE_BASE/dispatcharr/docker-compose.yml" # Ansible playbook for dispatcharr cat > "$PLAYBOOK_DIR/deploy-dispatcharr.yml" << 'EOF' --- - name: Deploy Dispatcharr to replicant hosts: replicant vars: service_name: dispatcharr service_dir: /home/maddox/docker/appdata/{{ service_name }} compose_src: "{{ playbook_dir }}/../compose-files/replicant/{{ service_name }}" tasks: - name: Create service directory ansible.builtin.file: path: "{{ service_dir }}" state: directory owner: maddox group: maddox mode: '0755' - name: Create data subdirectory ansible.builtin.file: path: "{{ service_dir }}/data" state: directory owner: maddox group: maddox mode: '0755' - name: Copy docker-compose.yml ansible.builtin.copy: src: "{{ compose_src }}/docker-compose.yml" dest: "{{ service_dir }}/docker-compose.yml" owner: maddox group: maddox mode: '0644' - name: Deploy container community.docker.docker_compose_v2: project_src: "{{ service_dir }}" state: present pull: always become: yes become_user: maddox EOF echo "✅ Created $PLAYBOOK_DIR/deploy-dispatcharr.yml" # ============================================================================ # COMBINED PLAYBOOK # ============================================================================ echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Creating: Combined deployment playbook" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" cat > "$PLAYBOOK_DIR/deploy-phase2-batch2.yml" << 'EOF' --- # Combined playbook for Phase 2 Batch 2 migrations # Run with: ansible-playbook playbooks/deploy-phase2-batch2.yml - name: Deploy TinyMediaManager import_playbook: deploy-tinymediamanager.yml - name: Deploy Autoscan import_playbook: deploy-autoscan.yml - name: Deploy ChannelTube import_playbook: deploy-channeltube.yml - name: Deploy Dispatcharr import_playbook: deploy-dispatcharr.yml EOF echo "✅ Created $PLAYBOOK_DIR/deploy-phase2-batch2.yml" # ============================================================================ # SUMMARY AND NEXT STEPS # ============================================================================ echo "" echo "╔════════════════════════════════════════════════════════════════════════╗" echo "║ FILES CREATED ║" echo "╚════════════════════════════════════════════════════════════════════════╝" echo "" echo "Compose files:" echo " - $COMPOSE_BASE/tinymediamanager/docker-compose.yml" echo " - $COMPOSE_BASE/autoscan/docker-compose.yml" echo " - $COMPOSE_BASE/channeltube/docker-compose.yml" echo " - $COMPOSE_BASE/dispatcharr/docker-compose.yml" echo "" echo "Playbooks:" echo " - $PLAYBOOK_DIR/deploy-tinymediamanager.yml" echo " - $PLAYBOOK_DIR/deploy-autoscan.yml" echo " - $PLAYBOOK_DIR/deploy-channeltube.yml" echo " - $PLAYBOOK_DIR/deploy-dispatcharr.yml" echo " - $PLAYBOOK_DIR/deploy-phase2-batch2.yml (combined)" echo "" echo "╔════════════════════════════════════════════════════════════════════════╗" echo "║ NEXT STEPS ║" echo "╚════════════════════════════════════════════════════════════════════════╝" echo "" echo "1. STOP OLD CONTAINERS on alien:" echo " ssh alien 'docker stop tinymediamanager autoscan channeltube dispatcharr'" echo "" echo "2. CREATE TARGET DIRECTORIES on replicant:" echo " ssh replicant 'mkdir -p /home/maddox/docker/appdata/{tinymediamanager,autoscan,channeltube}/config'" echo " ssh replicant 'mkdir -p /home/maddox/docker/appdata/dispatcharr/data'" echo "" echo "3. RSYNC DATA (run FROM replicant):" echo "" echo " ssh replicant" echo "" echo " # TinyMediaManager config:" echo " rsync -avP maddox@alien:/home/maddox/docker/appdata/tinymediamanager/config/ /home/maddox/docker/appdata/tinymediamanager/config/" echo "" echo " # Autoscan config (note: different source path on alien):" echo " rsync -avP maddox@alien:/volume1/docker/autoscan/ /home/maddox/docker/appdata/autoscan/config/" echo "" echo " # ChannelTube config:" echo " rsync -avP maddox@alien:/home/maddox/docker/appdata/channeltube/config/ /home/maddox/docker/appdata/channeltube/config/" echo "" echo " # Dispatcharr data (note: source is in vpn subdirectory):" echo " rsync -avP maddox@alien:/home/maddox/docker/appdata/vpn/dispatcharr/ /home/maddox/docker/appdata/dispatcharr/data/" echo "" echo "4. DEPLOY ALL (combined playbook):" echo " ansible-playbook playbooks/deploy-phase2-batch2.yml" echo "" echo " OR deploy individually:" echo " ansible-playbook playbooks/deploy-tinymediamanager.yml" echo " ansible-playbook playbooks/deploy-autoscan.yml" echo " ansible-playbook playbooks/deploy-channeltube.yml" echo " ansible-playbook playbooks/deploy-dispatcharr.yml" echo "" echo "5. VERIFY SERVICES:" echo " curl -s http://192.168.1.80:45800/ | head -5 # TinyMediaManager" echo " curl -s http://192.168.1.80:3030/health # Autoscan" echo " curl -s http://192.168.1.80:5444/ | head -5 # ChannelTube" echo " curl -s http://192.168.1.80:9191/ | head -5 # Dispatcharr" echo "" echo "6. UPDATE TRAEFIK (if applicable):" echo " - tinymediamanager: backend → 192.168.1.80:45800" echo " - autoscan: backend → 192.168.1.80:3030" echo " - channeltube: backend → 192.168.1.80:5444" echo " - dispatcharr: backend → 192.168.1.80:9191" echo "" echo "7. CLEANUP ALIEN:" echo " ssh alien 'docker rm tinymediamanager autoscan channeltube dispatcharr'" echo "" echo "8. GIT COMMIT:" echo " git add -A && git commit -m 'Phase 2 Batch 2: tinymediamanager, autoscan, channeltube, dispatcharr → replicant' && git push" echo "" echo "╔════════════════════════════════════════════════════════════════════════╗" echo "║ ℹ️ DISPATCHARR NOTES ║" echo "╚════════════════════════════════════════════════════════════════════════╝" echo "" echo "Dispatcharr is configured to use gluetun's HTTP proxy for VPN protection:" echo " - HTTP_PROXY=http://192.168.1.122:38888" echo " - HTTPS_PROXY=http://192.168.1.122:38888" echo "" echo "This routes HTTP/HTTPS traffic through the VPN while allowing dispatcharr" echo "to run on replicant with its own network stack and direct port access." echo "" echo "GPU Status:" echo " - /dev/dri is passed through (Intel QuickSync on pve-z620)" echo " - FirePro V3900 = decode-only (no hardware encoding)" echo " - NVIDIA env vars set for future pve-alien migration" echo " - Will use CPU transcoding until GTX 1070 is available" echo ""