scripts/migration/phase2-batch2-migration.sh
2026-01-27 01:57:38 +00:00

521 lines
19 KiB
Bash
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 ""