Auto-sync dyno.yml 2026-01-27 01:57
This commit is contained in:
parent
bb27e55004
commit
66ceea1359
9 changed files with 1812 additions and 25 deletions
|
|
@ -1267,7 +1267,7 @@ http:
|
|||
channeltube:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.1.252:5444
|
||||
- url: http://192.168.1.80:5444
|
||||
passHostHeader: false
|
||||
cyberchef:
|
||||
loadBalancer:
|
||||
|
|
@ -1283,7 +1283,7 @@ http:
|
|||
requests:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.1.252:5055
|
||||
- url: http://192.168.1.80:5055
|
||||
passHostHeader: false
|
||||
lidarr:
|
||||
loadBalancer:
|
||||
|
|
@ -1367,12 +1367,12 @@ http:
|
|||
autoscan:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.1.252:3030
|
||||
- url: http://192.168.1.80:3030
|
||||
passHostHeader: false
|
||||
watchstate:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.1.252:8585
|
||||
- url: http://192.168.1.80:8585
|
||||
passHostHeader: false
|
||||
node-red-het:
|
||||
loadBalancer:
|
||||
|
|
@ -1447,7 +1447,7 @@ http:
|
|||
dispatcharr:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.1.252:9191
|
||||
- url: http://192.168.1.80:9191
|
||||
technitium:
|
||||
loadBalancer:
|
||||
servers:
|
||||
|
|
|
|||
405
migration/ansible_controller.sh
Executable file
405
migration/ansible_controller.sh
Executable file
|
|
@ -0,0 +1,405 @@
|
|||
#!/bin/bash
|
||||
# Matrix Ansible Controller - Migration Script
|
||||
# Target: replicant (.80) - change if desired
|
||||
# Run this on the control server (CT 127)
|
||||
|
||||
set -e
|
||||
|
||||
SERVICE_NAME="matrix-ansible-controller"
|
||||
TARGET_HOST="replicant"
|
||||
COMPOSE_DIR=~/clustered-fucks/compose-files/${TARGET_HOST}/${SERVICE_NAME}
|
||||
PLAYBOOK_DIR=~/clustered-fucks/playbooks
|
||||
|
||||
echo "=== Matrix Ansible Controller Setup Script ==="
|
||||
echo "Service: ${SERVICE_NAME}"
|
||||
echo "Target: ${TARGET_HOST}"
|
||||
echo ""
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$COMPOSE_DIR"
|
||||
mkdir -p "$PLAYBOOK_DIR"
|
||||
|
||||
# =============================================================================
|
||||
# Dockerfile
|
||||
# =============================================================================
|
||||
cat > "$COMPOSE_DIR/Dockerfile" << 'EOF'
|
||||
# Matrix Ansible Controller
|
||||
# Portable container for managing matrix-docker-ansible-deploy playbook
|
||||
|
||||
FROM python:3.12-alpine
|
||||
|
||||
LABEL maintainer="maddox"
|
||||
LABEL description="Portable Ansible controller for matrix-docker-ansible-deploy"
|
||||
|
||||
# Install system dependencies
|
||||
RUN apk add --no-cache \
|
||||
# Core tools
|
||||
git \
|
||||
openssh-client \
|
||||
bash \
|
||||
curl \
|
||||
rsync \
|
||||
# Build dependencies for Python packages
|
||||
gcc \
|
||||
musl-dev \
|
||||
libffi-dev \
|
||||
openssl-dev \
|
||||
python3-dev \
|
||||
# For just command runner
|
||||
just \
|
||||
# Useful utilities
|
||||
nano \
|
||||
vim \
|
||||
tmux \
|
||||
jq
|
||||
|
||||
# Install Ansible and required Python packages
|
||||
RUN pip install --no-cache-dir \
|
||||
ansible>=2.17.0 \
|
||||
passlib \
|
||||
dnspython \
|
||||
netaddr \
|
||||
jmespath \
|
||||
docker \
|
||||
requests
|
||||
|
||||
# Install agru (faster ansible-galaxy alternative used by the playbook)
|
||||
RUN pip install --no-cache-dir agru
|
||||
|
||||
# Create working directories
|
||||
RUN mkdir -p /playbook /inventory /ssh
|
||||
|
||||
# Set up SSH directory with proper permissions
|
||||
RUN mkdir -p /root/.ssh && chmod 700 /root/.ssh
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
# Set working directory to playbook
|
||||
WORKDIR /playbook
|
||||
|
||||
# Default environment
|
||||
ENV ANSIBLE_HOST_KEY_CHECKING=False
|
||||
ENV ANSIBLE_FORCE_COLOR=True
|
||||
ENV TERM=xterm-256color
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
CMD ["/bin/bash"]
|
||||
EOF
|
||||
|
||||
echo "✅ Created $COMPOSE_DIR/Dockerfile"
|
||||
|
||||
# =============================================================================
|
||||
# Entrypoint Script
|
||||
# =============================================================================
|
||||
cat > "$COMPOSE_DIR/entrypoint.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Matrix Ansible Controller${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
# --- SSH Key Setup ---
|
||||
if [ -d "/ssh" ] && [ "$(ls -A /ssh 2>/dev/null)" ]; then
|
||||
echo -e "${GREEN}[SSH]${NC} Setting up SSH keys from /ssh mount..."
|
||||
cp -r /ssh/* /root/.ssh/ 2>/dev/null || true
|
||||
chmod 700 /root/.ssh
|
||||
chmod 600 /root/.ssh/* 2>/dev/null || true
|
||||
chmod 644 /root/.ssh/*.pub 2>/dev/null || true
|
||||
chmod 644 /root/.ssh/known_hosts 2>/dev/null || true
|
||||
chmod 644 /root/.ssh/config 2>/dev/null || true
|
||||
echo -e "${GREEN}[SSH]${NC} Keys configured"
|
||||
else
|
||||
echo -e "${YELLOW}[SSH]${NC} No SSH keys mounted at /ssh"
|
||||
echo -e "${YELLOW}[SSH]${NC} Mount with: -v ~/.ssh:/ssh:ro"
|
||||
fi
|
||||
|
||||
# --- Playbook Setup ---
|
||||
if [ ! -f "/playbook/setup.yml" ]; then
|
||||
echo -e "${GREEN}[PLAYBOOK]${NC} Cloning matrix-docker-ansible-deploy..."
|
||||
git clone https://github.com/spantaleev/matrix-docker-ansible-deploy.git /tmp/playbook
|
||||
mv /tmp/playbook/* /playbook/
|
||||
mv /tmp/playbook/.* /playbook/ 2>/dev/null || true
|
||||
rm -rf /tmp/playbook
|
||||
echo -e "${GREEN}[PLAYBOOK]${NC} Playbook cloned successfully"
|
||||
else
|
||||
echo -e "${GREEN}[PLAYBOOK]${NC} Playbook already present"
|
||||
fi
|
||||
|
||||
# --- Inventory Setup ---
|
||||
if [ -d "/inventory" ] && [ "$(ls -A /inventory 2>/dev/null)" ]; then
|
||||
echo -e "${GREEN}[INVENTORY]${NC} Linking inventory from /inventory mount..."
|
||||
# Remove default inventory if it exists
|
||||
rm -rf /playbook/inventory 2>/dev/null || true
|
||||
# Create symlink to mounted inventory
|
||||
ln -sf /inventory /playbook/inventory
|
||||
echo -e "${GREEN}[INVENTORY]${NC} Inventory linked: /playbook/inventory -> /inventory"
|
||||
else
|
||||
echo -e "${YELLOW}[INVENTORY]${NC} No inventory mounted at /inventory"
|
||||
echo -e "${YELLOW}[INVENTORY]${NC} Mount with: -v /path/to/inventory:/inventory"
|
||||
# Ensure default inventory directory exists
|
||||
mkdir -p /playbook/inventory
|
||||
fi
|
||||
|
||||
# --- Install/Update Ansible Roles ---
|
||||
if [ -f "/playbook/requirements.yml" ]; then
|
||||
if [ ! -d "/playbook/roles/galaxy" ] || [ "${UPDATE_ROLES:-false}" = "true" ]; then
|
||||
echo -e "${GREEN}[ROLES]${NC} Installing Ansible Galaxy roles..."
|
||||
cd /playbook
|
||||
if command -v agru &> /dev/null; then
|
||||
# Use agru if available (faster)
|
||||
agru
|
||||
else
|
||||
rm -rf roles/galaxy
|
||||
ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force
|
||||
fi
|
||||
echo -e "${GREEN}[ROLES]${NC} Roles installed successfully"
|
||||
else
|
||||
echo -e "${GREEN}[ROLES]${NC} Roles already installed (set UPDATE_ROLES=true to refresh)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Display Status ---
|
||||
echo ""
|
||||
echo -e "${BLUE}----------------------------------------${NC}"
|
||||
echo -e "${GREEN}Status:${NC}"
|
||||
echo -e " Ansible: $(ansible --version | head -1)"
|
||||
echo -e " Playbook: /playbook"
|
||||
echo -e " Inventory: /playbook/inventory"
|
||||
echo ""
|
||||
echo -e "${BLUE}Quick Commands:${NC}"
|
||||
echo -e " just install-all # Full installation"
|
||||
echo -e " just setup-all # Setup all components"
|
||||
echo -e " just roles # Update roles"
|
||||
echo -e " just update # git pull + update roles"
|
||||
echo ""
|
||||
echo -e " ansible-playbook -i inventory/hosts setup.yml --tags=install-all,start"
|
||||
echo ""
|
||||
echo -e "${BLUE}----------------------------------------${NC}"
|
||||
echo ""
|
||||
|
||||
# Execute command or start interactive shell
|
||||
exec "$@"
|
||||
EOF
|
||||
|
||||
echo "✅ Created $COMPOSE_DIR/entrypoint.sh"
|
||||
|
||||
# =============================================================================
|
||||
# Docker Compose
|
||||
# =============================================================================
|
||||
cat > "$COMPOSE_DIR/docker-compose.yml" << 'EOF'
|
||||
# Matrix Ansible Controller
|
||||
# Portable container for managing matrix-docker-ansible-deploy playbook
|
||||
#
|
||||
# Usage:
|
||||
# docker compose up -d
|
||||
# docker exec -it matrix-ansible-controller bash
|
||||
# just install-all
|
||||
|
||||
services:
|
||||
controller:
|
||||
build: .
|
||||
image: matrix-ansible-controller:latest
|
||||
container_name: matrix-ansible-controller
|
||||
hostname: matrix-controller
|
||||
|
||||
# Keep container running for interactive use
|
||||
stdin_open: true
|
||||
tty: true
|
||||
|
||||
volumes:
|
||||
# SSH keys (read-only) - for connecting to matrix server
|
||||
- /root/.ssh:/ssh:ro
|
||||
|
||||
# Persistent playbook directory (survives container rebuilds)
|
||||
- ./data/playbook:/playbook
|
||||
|
||||
# Your inventory configuration (vars.yml, hosts, etc.)
|
||||
- ./data/inventory:/inventory
|
||||
|
||||
# Persist ansible cache/facts
|
||||
- ./data/ansible-cache:/root/.ansible
|
||||
|
||||
environment:
|
||||
- ANSIBLE_HOST_KEY_CHECKING=False
|
||||
- ANSIBLE_FORCE_COLOR=True
|
||||
- UPDATE_ROLES=false
|
||||
|
||||
network_mode: bridge
|
||||
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
cpus: '2.0'
|
||||
|
||||
labels:
|
||||
- "com.centurylinklabs.watchtower.enable=false"
|
||||
|
||||
restart: unless-stopped
|
||||
EOF
|
||||
|
||||
echo "✅ Created $COMPOSE_DIR/docker-compose.yml"
|
||||
|
||||
# =============================================================================
|
||||
# Ansible Deployment Playbook
|
||||
# =============================================================================
|
||||
cat > "$PLAYBOOK_DIR/deploy-matrix-ansible-controller.yml" << 'EOF'
|
||||
---
|
||||
# Deploy Matrix Ansible Controller
|
||||
#
|
||||
# Usage:
|
||||
# ansible-playbook playbooks/deploy-matrix-ansible-controller.yml
|
||||
#
|
||||
# After deployment:
|
||||
# ssh replicant
|
||||
# docker exec -it matrix-ansible-controller bash
|
||||
# # Copy your vars.yml to data/inventory/host_vars/matrix.yourdomain.com/
|
||||
|
||||
- name: Deploy Matrix Ansible Controller
|
||||
hosts: replicant
|
||||
vars:
|
||||
service_name: matrix-ansible-controller
|
||||
service_dir: /home/maddox/docker/appdata/{{ service_name }}
|
||||
compose_src: "{{ playbook_dir }}/../compose-files/replicant/{{ service_name }}"
|
||||
|
||||
tasks:
|
||||
- name: Create service directory structure
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "{{ service_dir }}"
|
||||
- "{{ service_dir }}/data"
|
||||
- "{{ service_dir }}/data/playbook"
|
||||
- "{{ service_dir }}/data/inventory"
|
||||
- "{{ service_dir }}/data/inventory/host_vars"
|
||||
- "{{ service_dir }}/data/ansible-cache"
|
||||
|
||||
- name: Copy Dockerfile
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/Dockerfile"
|
||||
dest: "{{ service_dir }}/Dockerfile"
|
||||
mode: '0644'
|
||||
|
||||
- name: Copy entrypoint script
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/entrypoint.sh"
|
||||
dest: "{{ service_dir }}/entrypoint.sh"
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ service_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Build Docker image
|
||||
community.docker.docker_image:
|
||||
name: matrix-ansible-controller
|
||||
tag: latest
|
||||
source: build
|
||||
build:
|
||||
path: "{{ service_dir }}"
|
||||
pull: yes
|
||||
state: present
|
||||
force_source: yes
|
||||
|
||||
- name: Deploy container
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ service_dir }}"
|
||||
state: present
|
||||
pull: always
|
||||
|
||||
- name: Display next steps
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
|
||||
✅ Matrix Ansible Controller deployed!
|
||||
|
||||
=== NEXT STEPS ===
|
||||
|
||||
1. Copy your Matrix inventory to the container:
|
||||
|
||||
ssh replicant
|
||||
cd /home/maddox/docker/appdata/matrix-ansible-controller/data/inventory
|
||||
|
||||
# Create the structure:
|
||||
mkdir -p host_vars/matrix.yourdomain.com
|
||||
|
||||
# Copy your vars.yml (from wherever it currently lives):
|
||||
# Option A: From another machine via scp
|
||||
# Option B: Create/paste manually
|
||||
|
||||
# Also create/copy the hosts file:
|
||||
cat > hosts << 'HOSTS'
|
||||
[matrix_servers]
|
||||
matrix.yourdomain.com ansible_host=YOUR_MATRIX_IP ansible_ssh_user=root
|
||||
HOSTS
|
||||
|
||||
2. Enter the container and test:
|
||||
|
||||
docker exec -it matrix-ansible-controller bash
|
||||
ansible -i inventory/hosts all -m ping
|
||||
|
||||
3. Run Matrix updates:
|
||||
|
||||
just update # Update playbook + roles
|
||||
just install-all # Deploy changes
|
||||
|
||||
===================================
|
||||
EOF
|
||||
|
||||
echo "✅ Created $PLAYBOOK_DIR/deploy-matrix-ansible-controller.yml"
|
||||
|
||||
# =============================================================================
|
||||
# Summary
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "==========================================="
|
||||
echo " FILES CREATED"
|
||||
echo "==========================================="
|
||||
echo ""
|
||||
echo "Compose files:"
|
||||
echo " $COMPOSE_DIR/Dockerfile"
|
||||
echo " $COMPOSE_DIR/entrypoint.sh"
|
||||
echo " $COMPOSE_DIR/docker-compose.yml"
|
||||
echo ""
|
||||
echo "Playbook:"
|
||||
echo " $PLAYBOOK_DIR/deploy-matrix-ansible-controller.yml"
|
||||
echo ""
|
||||
echo "==========================================="
|
||||
echo " NEXT STEPS"
|
||||
echo "==========================================="
|
||||
echo ""
|
||||
echo "1. DEPLOY:"
|
||||
echo " ansible-playbook playbooks/deploy-matrix-ansible-controller.yml"
|
||||
echo ""
|
||||
echo "2. VERIFY:"
|
||||
echo " ssh replicant 'docker ps | grep matrix-ansible'"
|
||||
echo ""
|
||||
echo "3. COPY YOUR MATRIX INVENTORY:"
|
||||
echo " ssh replicant"
|
||||
echo " cd /home/maddox/docker/appdata/matrix-ansible-controller/data/inventory"
|
||||
echo " mkdir -p host_vars/matrix.yourdomain.com"
|
||||
echo " # Then copy/create your vars.yml and hosts file"
|
||||
echo ""
|
||||
echo "4. TEST:"
|
||||
echo " docker exec -it matrix-ansible-controller bash"
|
||||
echo " ansible -i inventory/hosts all -m ping"
|
||||
echo " just install-all"
|
||||
echo ""
|
||||
echo "5. COMMIT TO GIT:"
|
||||
echo " git add -A && git commit -m 'Add matrix-ansible-controller' && git push"
|
||||
echo ""
|
||||
echo "==========================================="
|
||||
150
migration/migrate-homepage.sh
Executable file
150
migration/migrate-homepage.sh
Executable file
|
|
@ -0,0 +1,150 @@
|
|||
#!/bin/bash
|
||||
# Homepage Migration Script
|
||||
# Target: replicant (.80)
|
||||
# Run this on the control server (CT 127)
|
||||
|
||||
set -e
|
||||
|
||||
COMPOSE_DIR=~/clustered-fucks/compose-files/replicant/homepage
|
||||
PLAYBOOK_DIR=~/clustered-fucks/playbooks
|
||||
|
||||
echo "=== Homepage Migration Script ==="
|
||||
echo "Target: replicant (.80)"
|
||||
echo ""
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$COMPOSE_DIR"
|
||||
mkdir -p "$PLAYBOOK_DIR"
|
||||
|
||||
# Create docker-compose.yml
|
||||
cat > "$COMPOSE_DIR/docker-compose.yml" << 'EOF'
|
||||
services:
|
||||
homepage:
|
||||
image: ghcr.io/gethomepage/homepage:latest
|
||||
container_name: homepage
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- HOMEPAGE_ALLOWED_HOSTS=192.168.1.80:3305,home.3ddbrewery.com,*
|
||||
volumes:
|
||||
- ./config:/app/config
|
||||
ports:
|
||||
- "3305:3000"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
cpus: '1.0'
|
||||
labels:
|
||||
- "autoheal=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "✅ Created $COMPOSE_DIR/docker-compose.yml"
|
||||
|
||||
# Create Ansible playbook
|
||||
cat > "$PLAYBOOK_DIR/deploy-homepage.yml" << 'EOF'
|
||||
---
|
||||
- name: Deploy Homepage to replicant
|
||||
hosts: replicant
|
||||
vars:
|
||||
service_name: homepage
|
||||
service_dir: "{{ 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
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ service_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Create config directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ service_dir }}/config"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Pull latest image
|
||||
community.docker.docker_image:
|
||||
name: ghcr.io/gethomepage/homepage:latest
|
||||
source: pull
|
||||
force_source: yes
|
||||
|
||||
- name: Deploy Homepage
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ service_dir }}"
|
||||
state: present
|
||||
pull: missing
|
||||
register: deploy_result
|
||||
|
||||
- name: Show deployment result
|
||||
ansible.builtin.debug:
|
||||
msg: "Homepage deployed: {{ deploy_result.changed }}"
|
||||
|
||||
- name: Wait for container to be healthy
|
||||
ansible.builtin.shell: |
|
||||
for i in {1..30}; do
|
||||
status=$(docker inspect --format='{{ "{{" }}.State.Health.Status{{ "}}" }}' homepage 2>/dev/null || echo "starting")
|
||||
if [ "$status" = "healthy" ]; then
|
||||
echo "Container is healthy"
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo "Warning: Container not healthy after 60s"
|
||||
docker logs homepage 2>&1 | tail -20
|
||||
register: health_check
|
||||
changed_when: false
|
||||
|
||||
- name: Display health status
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ health_check.stdout }}"
|
||||
EOF
|
||||
|
||||
echo "✅ Created $PLAYBOOK_DIR/deploy-homepage.yml"
|
||||
|
||||
echo ""
|
||||
echo "=== Files Created ==="
|
||||
echo " $COMPOSE_DIR/docker-compose.yml"
|
||||
echo " $PLAYBOOK_DIR/deploy-homepage.yml"
|
||||
echo ""
|
||||
echo "=== Next Steps ==="
|
||||
echo ""
|
||||
echo "1. RSYNC CONFIG FROM ALIEN (do this first!):"
|
||||
echo " ssh alien 'docker stop homepage'"
|
||||
echo " rsync -avP maddox@alien:/home/maddox/docker/appdata/homepage/config/ \\"
|
||||
echo " maddox@replicant:/home/maddox/docker/appdata/homepage/config/"
|
||||
echo ""
|
||||
echo "2. DEPLOY TO REPLICANT:"
|
||||
echo " cd ~/clustered-fucks"
|
||||
echo " ansible-playbook playbooks/deploy-homepage.yml"
|
||||
echo ""
|
||||
echo "3. VERIFY:"
|
||||
echo " curl -s http://192.168.1.80:3305/api/healthcheck"
|
||||
echo " # or visit http://192.168.1.80:3305 in browser"
|
||||
echo ""
|
||||
echo "4. UPDATE TRAEFIK (on alien - update IP from .252 to .80):"
|
||||
echo " # Edit /home/maddox/docker/appdata/traefik/config/config.yml"
|
||||
echo " # Change homepage URL from 192.168.1.252:3305 to 192.168.1.80:3305"
|
||||
echo ""
|
||||
echo "5. CLEANUP ALIEN (after verification):"
|
||||
echo " ssh alien 'docker rm homepage'"
|
||||
echo ""
|
||||
echo "6. COMMIT TO GIT:"
|
||||
echo " cd ~/clustered-fucks"
|
||||
echo " git add -A && git commit -m 'Deploy homepage to replicant' && git push"
|
||||
echo ""
|
||||
195
migration/migrate-jellyseer-watchstate.yml
Executable file
195
migration/migrate-jellyseer-watchstate.yml
Executable file
|
|
@ -0,0 +1,195 @@
|
|||
#!/bin/bash
|
||||
# Watchstate + Jellyseerr Migration Script
|
||||
# Target: replicant (.80)
|
||||
# Run this on the control server (CT 127)
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Watchstate + Jellyseerr Migration Script ==="
|
||||
echo "Target: replicant (192.168.1.80)"
|
||||
echo ""
|
||||
|
||||
# ============================================
|
||||
# WATCHSTATE
|
||||
# ============================================
|
||||
|
||||
WATCHSTATE_COMPOSE_DIR=~/clustered-fucks/compose-files/replicant/watchstate
|
||||
PLAYBOOK_DIR=~/clustered-fucks/playbooks
|
||||
|
||||
mkdir -p "$WATCHSTATE_COMPOSE_DIR"
|
||||
mkdir -p "$PLAYBOOK_DIR"
|
||||
|
||||
cat > "$WATCHSTATE_COMPOSE_DIR/docker-compose.yml" << 'EOF'
|
||||
services:
|
||||
watchstate:
|
||||
image: ghcr.io/arabcoders/watchstate:latest
|
||||
container_name: watchstate
|
||||
user: "1000:1000"
|
||||
environment:
|
||||
- TZ=America/Indiana/Indianapolis
|
||||
volumes:
|
||||
- ./config:/config:rw
|
||||
ports:
|
||||
- "8585:8080"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
cpus: '1.0'
|
||||
labels:
|
||||
- "autoheal=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/v1/api/system/healthcheck || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "✅ Created $WATCHSTATE_COMPOSE_DIR/docker-compose.yml"
|
||||
|
||||
cat > "$PLAYBOOK_DIR/deploy-watchstate.yml" << 'EOF'
|
||||
---
|
||||
- name: Deploy Watchstate to replicant
|
||||
hosts: replicant
|
||||
vars:
|
||||
service_name: watchstate
|
||||
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
|
||||
mode: '0755'
|
||||
|
||||
- name: Create config subdirectory
|
||||
ansible.builtin.file:
|
||||
path: "{{ service_dir }}/config"
|
||||
state: directory
|
||||
owner: "1000"
|
||||
group: "1000"
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ service_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Deploy container
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ service_dir }}"
|
||||
state: present
|
||||
pull: always
|
||||
EOF
|
||||
|
||||
echo "✅ Created $PLAYBOOK_DIR/deploy-watchstate.yml"
|
||||
|
||||
# ============================================
|
||||
# JELLYSEERR
|
||||
# ============================================
|
||||
|
||||
JELLYSEERR_COMPOSE_DIR=~/clustered-fucks/compose-files/replicant/jellyseerr
|
||||
|
||||
mkdir -p "$JELLYSEERR_COMPOSE_DIR"
|
||||
|
||||
cat > "$JELLYSEERR_COMPOSE_DIR/docker-compose.yml" << 'EOF'
|
||||
services:
|
||||
jellyseerr:
|
||||
image: fallenbagel/jellyseerr:latest
|
||||
container_name: jellyseerr
|
||||
environment:
|
||||
- LOG_LEVEL=info
|
||||
- TZ=America/Indiana/Indianapolis
|
||||
volumes:
|
||||
- ./config:/app/config
|
||||
ports:
|
||||
- "5055:5055"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
cpus: '1.0'
|
||||
labels:
|
||||
- "autoheal=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "✅ Created $JELLYSEERR_COMPOSE_DIR/docker-compose.yml"
|
||||
|
||||
cat > "$PLAYBOOK_DIR/deploy-jellyseerr.yml" << 'EOF'
|
||||
---
|
||||
- name: Deploy Jellyseerr to replicant
|
||||
hosts: replicant
|
||||
vars:
|
||||
service_name: jellyseerr
|
||||
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
|
||||
mode: '0755'
|
||||
|
||||
- name: Create config subdirectory
|
||||
ansible.builtin.file:
|
||||
path: "{{ service_dir }}/config"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ service_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Deploy container
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ service_dir }}"
|
||||
state: present
|
||||
pull: always
|
||||
EOF
|
||||
|
||||
echo "✅ Created $PLAYBOOK_DIR/deploy-jellyseerr.yml"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "=== MIGRATION STEPS ==="
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "--- WATCHSTATE ---"
|
||||
echo "1. STOP: ssh alien 'docker stop watchstate'"
|
||||
echo "2. RSYNC: ssh replicant"
|
||||
echo " rsync -avP maddox@alien:/home/maddox/docker/appdata/watchstate/ /home/maddox/docker/appdata/watchstate/config/"
|
||||
echo "3. DEPLOY: ansible-playbook playbooks/deploy-watchstate.yml"
|
||||
echo "4. VERIFY: curl http://192.168.1.80:8585/v1/api/system/healthcheck"
|
||||
echo ""
|
||||
echo "--- JELLYSEERR ---"
|
||||
echo "5. STOP: ssh alien 'docker stop jellyseerr'"
|
||||
echo "6. RSYNC: ssh replicant"
|
||||
echo " rsync -avP maddox@alien:/home/maddox/docker/appdata/jellyseerr/ /home/maddox/docker/appdata/jellyseerr/config/"
|
||||
echo "7. DEPLOY: ansible-playbook playbooks/deploy-jellyseerr.yml"
|
||||
echo "8. VERIFY: curl -I http://192.168.1.80:5055"
|
||||
echo ""
|
||||
echo "--- CLEANUP ---"
|
||||
echo "9. UPDATE TRAEFIK: Change backend IPs to 192.168.1.80"
|
||||
echo "10. CLEANUP: ssh alien 'docker rm watchstate jellyseerr'"
|
||||
echo "11. COMMIT: git add -A && git commit -m 'Migrate watchstate + jellyseerr to replicant' && git push"
|
||||
141
migration/migrate-ntfy.sh
Executable file
141
migration/migrate-ntfy.sh
Executable file
|
|
@ -0,0 +1,141 @@
|
|||
#!/bin/bash
|
||||
# ntfy Migration Script
|
||||
# Target: network-services (.121)
|
||||
# Run this on the control server (CT 127)
|
||||
|
||||
set -e
|
||||
|
||||
COMPOSE_DIR=~/clustered-fucks/compose-files/network-services/ntfy
|
||||
PLAYBOOK_DIR=~/clustered-fucks/playbooks
|
||||
|
||||
echo "=== ntfy Migration Script ==="
|
||||
echo "Target: network-services (.121)"
|
||||
echo "⚠️ CRITICAL: This is your notification hub - expect brief cluster-wide notification outage"
|
||||
echo ""
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$COMPOSE_DIR"
|
||||
mkdir -p "$PLAYBOOK_DIR"
|
||||
|
||||
# Create docker-compose.yml
|
||||
cat > "$COMPOSE_DIR/docker-compose.yml" << 'EOF'
|
||||
services:
|
||||
ntfy:
|
||||
image: binwiederhier/ntfy:latest
|
||||
container_name: ntfy
|
||||
command: serve
|
||||
environment:
|
||||
- NTFY_BASE_URL=https://ntfy.3ddbrewery.com
|
||||
- NTFY_BEHIND_PROXY=true
|
||||
volumes:
|
||||
- ./data:/var/lib/ntfy
|
||||
- ./cache:/var/cache/ntfy
|
||||
ports:
|
||||
- "6741:80"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
cpus: '0.5'
|
||||
labels:
|
||||
- "autoheal=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "✅ Created $COMPOSE_DIR/docker-compose.yml"
|
||||
|
||||
# Create Ansible playbook
|
||||
cat > "$PLAYBOOK_DIR/deploy-ntfy.yml" << 'EOF'
|
||||
---
|
||||
- name: Deploy ntfy to network-services
|
||||
hosts: network-services
|
||||
vars:
|
||||
service_name: ntfy
|
||||
service_dir: "{{ docker_appdata }}/{{ service_name }}"
|
||||
compose_src: "{{ playbook_dir }}/../compose-files/network-services/{{ service_name }}"
|
||||
|
||||
tasks:
|
||||
- name: Create service directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ service_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Create data subdirectory
|
||||
ansible.builtin.file:
|
||||
path: "{{ service_dir }}/data"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Create cache subdirectory
|
||||
ansible.builtin.file:
|
||||
path: "{{ service_dir }}/cache"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ service_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Pull latest image
|
||||
community.docker.docker_image:
|
||||
name: binwiederhier/ntfy:latest
|
||||
source: pull
|
||||
force_source: yes
|
||||
|
||||
- name: Deploy container
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ service_dir }}"
|
||||
state: present
|
||||
pull: missing
|
||||
EOF
|
||||
|
||||
echo "✅ Created $PLAYBOOK_DIR/deploy-ntfy.yml"
|
||||
|
||||
echo ""
|
||||
echo "=== FILES CREATED ==="
|
||||
echo " - $COMPOSE_DIR/docker-compose.yml"
|
||||
echo " - $PLAYBOOK_DIR/deploy-ntfy.yml"
|
||||
echo ""
|
||||
echo "=== MIGRATION STEPS ==="
|
||||
echo ""
|
||||
echo "1. STOP OLD CONTAINER:"
|
||||
echo " ssh alien 'docker stop ntfy'"
|
||||
echo ""
|
||||
echo "2. RSYNC DATA (run from network-services):"
|
||||
echo " ssh network-services"
|
||||
echo " sudo mkdir -p /home/docker/appdata/ntfy/{data,cache}"
|
||||
echo " sudo rsync -avP maddox@alien:/home/maddox/docker/appdata/ntfy/ /home/docker/appdata/ntfy/data/"
|
||||
echo " sudo rsync -avP maddox@alien:/home/maddox/docker/appdata/ntfy/cache/ /home/docker/appdata/ntfy/cache/"
|
||||
echo " exit"
|
||||
echo ""
|
||||
echo "3. DEPLOY:"
|
||||
echo " ansible-playbook playbooks/deploy-ntfy.yml"
|
||||
echo ""
|
||||
echo "4. VERIFY:"
|
||||
echo " curl -s http://192.168.1.121:6741/v1/health"
|
||||
echo " # Test notification:"
|
||||
echo " curl -d 'Migration test' http://192.168.1.121:6741/test-migration"
|
||||
echo ""
|
||||
echo "5. UPDATE TRAEFIK (on alien):"
|
||||
echo " # Change ntfy backend from 192.168.1.252:6741 to 192.168.1.121:6741"
|
||||
echo ""
|
||||
echo "6. VERIFY EXTERNAL ACCESS:"
|
||||
echo " curl -d 'External test' https://ntfy.3ddbrewery.com/test-migration"
|
||||
echo ""
|
||||
echo "7. CLEANUP:"
|
||||
echo " ssh alien 'docker rm ntfy'"
|
||||
echo ""
|
||||
echo "8. COMMIT:"
|
||||
echo " git add -A && git commit -m 'Migrate ntfy to network-services (.121)' && git push"
|
||||
echo ""
|
||||
echo "=== DONE ==="
|
||||
161
migration/migrate-sb.sh
Executable file
161
migration/migrate-sb.sh
Executable file
|
|
@ -0,0 +1,161 @@
|
|||
#!/bin/bash
|
||||
# SilverBullet Migration Script
|
||||
# Target: databases (.81)
|
||||
# Run this on the control server (CT 127)
|
||||
|
||||
set -e
|
||||
|
||||
COMPOSE_DIR=~/clustered-fucks/compose-files/databases/silverbullet
|
||||
PLAYBOOK_DIR=~/clustered-fucks/playbooks
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$COMPOSE_DIR"
|
||||
mkdir -p "$PLAYBOOK_DIR"
|
||||
|
||||
# Create docker-compose.yml
|
||||
cat > "$COMPOSE_DIR/docker-compose.yml" << 'EOF'
|
||||
services:
|
||||
silverbullet:
|
||||
image: ghcr.io/silverbulletmd/silverbullet
|
||||
container_name: silverbullet
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./space:/space
|
||||
ports:
|
||||
- "53510:3000"
|
||||
networks:
|
||||
- proxy
|
||||
labels:
|
||||
- "autoheal=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
cpus: '0.5'
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl --fail http://localhost:3000/.ping || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
# Create .env file
|
||||
cat > "$COMPOSE_DIR/.env" << 'EOF'
|
||||
SB_USER=maddox:./sk8nh8
|
||||
SB_HOSTNAME=0.0.0.0
|
||||
SB_FOLDER=/space
|
||||
EOF
|
||||
|
||||
# Create Ansible playbook
|
||||
cat > "$PLAYBOOK_DIR/deploy-silverbullet.yml" << 'EOF'
|
||||
---
|
||||
- name: Deploy SilverBullet to databases
|
||||
hosts: databases
|
||||
become: yes
|
||||
vars:
|
||||
appdata_path: /home/docker/appdata/silverbullet
|
||||
compose_src: ~/clustered-fucks/compose-files/databases/silverbullet
|
||||
|
||||
tasks:
|
||||
- name: Create appdata directory
|
||||
file:
|
||||
path: "{{ appdata_path }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ appdata_path }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Copy .env file
|
||||
copy:
|
||||
src: "{{ compose_src }}/.env"
|
||||
dest: "{{ appdata_path }}/.env"
|
||||
mode: '0600'
|
||||
|
||||
- name: Pull latest image
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ appdata_path }}"
|
||||
pull: always
|
||||
state: present
|
||||
|
||||
- name: Start SilverBullet
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ appdata_path }}"
|
||||
state: present
|
||||
|
||||
- name: Wait for container to be healthy
|
||||
shell: |
|
||||
for i in {1..30}; do
|
||||
status=$(docker inspect --format='{{.State.Health.Status}}' silverbullet 2>/dev/null || echo "not_found")
|
||||
if [ "$status" = "healthy" ]; then
|
||||
echo "Container is healthy"
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo "Timeout waiting for healthy status"
|
||||
exit 1
|
||||
register: health_check
|
||||
changed_when: false
|
||||
|
||||
- name: Show container status
|
||||
shell: docker ps --filter name=silverbullet --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
register: container_status
|
||||
changed_when: false
|
||||
|
||||
- name: Display status
|
||||
debug:
|
||||
var: container_status.stdout_lines
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " SilverBullet Migration - Next Steps"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "1. RSYNC DATA FROM ALIEN"
|
||||
echo " SSH to databases and pull the space directory:"
|
||||
echo ""
|
||||
echo " ssh databases"
|
||||
echo " sudo mkdir -p /home/docker/appdata/silverbullet"
|
||||
echo " sudo rsync -avP maddox@alien:/home/maddox/docker/appdata/silverbullet/space/ /home/docker/appdata/silverbullet/space/"
|
||||
echo " exit"
|
||||
echo ""
|
||||
echo "2. DEPLOY VIA ANSIBLE"
|
||||
echo " cd ~/clustered-fucks"
|
||||
echo " ansible-playbook playbooks/deploy-silverbullet.yml"
|
||||
echo ""
|
||||
echo "3. VERIFY"
|
||||
echo " curl -u maddox:./sk8nh8 http://192.168.1.81:53510/.ping"
|
||||
echo " # Should return: OK"
|
||||
echo ""
|
||||
echo "4. UPDATE TRAEFIK ON ALIEN"
|
||||
echo " Edit Traefik dynamic config to point silverbullet to:"
|
||||
echo " http://192.168.1.81:53510"
|
||||
echo ""
|
||||
echo "5. TEST VIA DOMAIN"
|
||||
echo " Access via your SilverBullet domain"
|
||||
echo " Verify Authentik auth + SilverBullet loads"
|
||||
echo ""
|
||||
echo "6. CLEANUP ALIEN"
|
||||
echo " ssh alien"
|
||||
echo " cd /home/maddox/docker/appdata/silverbullet"
|
||||
echo " docker compose down"
|
||||
echo ""
|
||||
echo "7. COMMIT TO GIT"
|
||||
echo " cd ~/clustered-fucks"
|
||||
echo " git add -A"
|
||||
echo " git commit -m 'Add SilverBullet migration to databases'"
|
||||
echo " git push"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
193
migration/migrate-wecheck-cyberchef.sh
Executable file
193
migration/migrate-wecheck-cyberchef.sh
Executable file
|
|
@ -0,0 +1,193 @@
|
|||
#!/bin/bash
|
||||
# Web-Check + CyberChef Migration Script
|
||||
# Target: replicant (.80)
|
||||
# Run this on the control server (CT 127)
|
||||
|
||||
set -e
|
||||
|
||||
COMPOSE_BASE=~/clustered-fucks/compose-files/replicant
|
||||
PLAYBOOK_DIR=~/clustered-fucks/playbooks
|
||||
|
||||
echo "=== Web-Check + CyberChef Migration Script ==="
|
||||
echo "Target: replicant (.80)"
|
||||
echo "Both are STATELESS - no data to rsync!"
|
||||
echo ""
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$COMPOSE_BASE/web-check"
|
||||
mkdir -p "$COMPOSE_BASE/cyberchef"
|
||||
mkdir -p "$PLAYBOOK_DIR"
|
||||
|
||||
# ============================================
|
||||
# WEB-CHECK
|
||||
# ============================================
|
||||
|
||||
cat > "$COMPOSE_BASE/web-check/docker-compose.yml" << 'EOF'
|
||||
services:
|
||||
web-check:
|
||||
image: lissy93/web-check:latest
|
||||
container_name: web-check
|
||||
ports:
|
||||
- "6160:3000"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
cpus: '0.5'
|
||||
labels:
|
||||
- "autoheal=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "✅ Created $COMPOSE_BASE/web-check/docker-compose.yml"
|
||||
|
||||
cat > "$PLAYBOOK_DIR/deploy-web-check.yml" << 'EOF'
|
||||
---
|
||||
- name: Deploy Web-Check to replicant
|
||||
hosts: replicant
|
||||
vars:
|
||||
service_name: web-check
|
||||
service_dir: "{{ 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
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ service_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Pull latest image
|
||||
community.docker.docker_image:
|
||||
name: lissy93/web-check:latest
|
||||
source: pull
|
||||
force_source: yes
|
||||
|
||||
- name: Deploy container
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ service_dir }}"
|
||||
state: present
|
||||
pull: missing
|
||||
EOF
|
||||
|
||||
echo "✅ Created $PLAYBOOK_DIR/deploy-web-check.yml"
|
||||
|
||||
# ============================================
|
||||
# CYBERCHEF
|
||||
# ============================================
|
||||
|
||||
cat > "$COMPOSE_BASE/cyberchef/docker-compose.yml" << 'EOF'
|
||||
services:
|
||||
cyberchef:
|
||||
image: mpepping/cyberchef:latest
|
||||
container_name: cyberchef
|
||||
ports:
|
||||
- "7318:8000"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
cpus: '0.5'
|
||||
labels:
|
||||
- "autoheal=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "✅ Created $COMPOSE_BASE/cyberchef/docker-compose.yml"
|
||||
|
||||
cat > "$PLAYBOOK_DIR/deploy-cyberchef.yml" << 'EOF'
|
||||
---
|
||||
- name: Deploy CyberChef to replicant
|
||||
hosts: replicant
|
||||
vars:
|
||||
service_name: cyberchef
|
||||
service_dir: "{{ 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
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: "{{ compose_src }}/docker-compose.yml"
|
||||
dest: "{{ service_dir }}/docker-compose.yml"
|
||||
mode: '0644'
|
||||
|
||||
- name: Pull latest image
|
||||
community.docker.docker_image:
|
||||
name: mpepping/cyberchef:latest
|
||||
source: pull
|
||||
force_source: yes
|
||||
|
||||
- name: Deploy container
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ service_dir }}"
|
||||
state: present
|
||||
pull: missing
|
||||
EOF
|
||||
|
||||
echo "✅ Created $PLAYBOOK_DIR/deploy-cyberchef.yml"
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "=== Files Created ==="
|
||||
echo "============================================"
|
||||
echo " $COMPOSE_BASE/web-check/docker-compose.yml"
|
||||
echo " $COMPOSE_BASE/cyberchef/docker-compose.yml"
|
||||
echo " $PLAYBOOK_DIR/deploy-web-check.yml"
|
||||
echo " $PLAYBOOK_DIR/deploy-cyberchef.yml"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "=== Next Steps ==="
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "1. STOP OLD CONTAINERS ON ALIEN:"
|
||||
echo " ssh alien 'docker stop web-check cyberchef'"
|
||||
echo ""
|
||||
echo "2. DEPLOY VIA ANSIBLE (no rsync needed - stateless!):"
|
||||
echo " cd ~/clustered-fucks"
|
||||
echo " ansible-playbook playbooks/deploy-web-check.yml"
|
||||
echo " ansible-playbook playbooks/deploy-cyberchef.yml"
|
||||
echo ""
|
||||
echo "3. VERIFY:"
|
||||
echo " curl -s -o /dev/null -w '%{http_code}' http://192.168.1.80:6160/"
|
||||
echo " curl -s -o /dev/null -w '%{http_code}' http://192.168.1.80:7318/"
|
||||
echo ""
|
||||
echo "4. UPDATE TRAEFIK (on alien):"
|
||||
echo " # Edit traefik config, change web-check URL to .80:6160"
|
||||
echo " # Edit traefik config, change cyberchef URL to .80:7318"
|
||||
echo ""
|
||||
echo "5. CLEANUP ALIEN:"
|
||||
echo " ssh alien 'docker rm web-check cyberchef'"
|
||||
echo ""
|
||||
echo "6. COMMIT TO GIT:"
|
||||
echo " cd ~/clustered-fucks"
|
||||
echo " git add -A && git commit -m 'Deploy web-check and cyberchef to replicant' && git push"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "Done! Both services are stateless - no data migration needed."
|
||||
echo "============================================"
|
||||
521
migration/phase2-batch2-migration.sh
Executable file
521
migration/phase2-batch2-migration.sh
Executable file
|
|
@ -0,0 +1,521 @@
|
|||
#!/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 ""
|
||||
59
sync-dyno.sh
59
sync-dyno.sh
|
|
@ -1,31 +1,52 @@
|
|||
#!/bin/bash
|
||||
# Sync dyno.yml from Hetzner host "im"
|
||||
# Source: im:/matrix/traefik/config/dyno.yml
|
||||
# Destination: ~/scripts/configs/dyno.yml
|
||||
# Runs via cron every 5 minutes
|
||||
# Auto-commits and pushes if changes detected
|
||||
|
||||
set -e
|
||||
SCRIPTS_DIR=~/scripts
|
||||
DEST_FILE="$SCRIPTS_DIR/configs/dyno.yml"
|
||||
LOG_FILE="$SCRIPTS_DIR/logs/sync-dyno.log"
|
||||
|
||||
DEST_DIR=~/scripts/configs
|
||||
DEST_FILE="$DEST_DIR/dyno.yml"
|
||||
# Ensure dirs exist
|
||||
mkdir -p "$SCRIPTS_DIR/configs"
|
||||
mkdir -p "$SCRIPTS_DIR/logs"
|
||||
|
||||
mkdir -p "$DEST_DIR"
|
||||
# Logging function
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
echo "Syncing dyno.yml from im..."
|
||||
rsync -avP im:/matrix/traefik/config/dyno.yml "$DEST_FILE"
|
||||
# Rotate log if > 1MB
|
||||
if [ -f "$LOG_FILE" ] && [ $(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0) -gt 1048576 ]; then
|
||||
mv "$LOG_FILE" "$LOG_FILE.old"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Synced to: $DEST_FILE"
|
||||
echo ""
|
||||
# Sync file
|
||||
if ! rsync -az im:/matrix/traefik/config/dyno.yml "$DEST_FILE" 2>> "$LOG_FILE"; then
|
||||
log "ERROR: rsync failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Show diff if in git repo
|
||||
if [ -d ~/scripts/.git ]; then
|
||||
cd ~/scripts
|
||||
# Check for changes and auto-commit/push
|
||||
cd "$SCRIPTS_DIR"
|
||||
if [ -d .git ]; then
|
||||
if ! git diff --quiet configs/dyno.yml 2>/dev/null; then
|
||||
echo "Changes detected:"
|
||||
git diff configs/dyno.yml
|
||||
echo ""
|
||||
echo "To commit: cd ~/scripts && git add -A && git commit -m 'Update dyno.yml'"
|
||||
log "Changes detected in dyno.yml"
|
||||
|
||||
# Auto-commit
|
||||
git add configs/dyno.yml
|
||||
git commit -m "Auto-sync dyno.yml $(date '+%Y-%m-%d %H:%M')" >> "$LOG_FILE" 2>&1
|
||||
log "Committed changes"
|
||||
|
||||
# Auto-push (if remote configured)
|
||||
if git remote | grep -q origin; then
|
||||
if git push origin main >> "$LOG_FILE" 2>&1; then
|
||||
log "Pushed to origin"
|
||||
else
|
||||
echo "No changes from last sync."
|
||||
log "ERROR: Push failed"
|
||||
fi
|
||||
else
|
||||
log "No remote configured, skipping push"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
Loading…
Reference in a new issue