import paramiko import sys import time sys.stdout.reconfigure(encoding='utf-8') c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect('140.44.4.71', username='root', key_filename=r'C:\Users\Snarf\.ssh\id_ed25519_snarfnet', timeout=10) def run(cmd): print(f"\n>>> {cmd}") _, o, e = c.exec_command(cmd) res = o.read().decode().strip() err = e.read().decode().strip() if res: print(res) if err: print("[stderr]", err) return res print("=== 1. Removing Old Failing Watchtower Stack ===") run("docker stack rm watchtower") time.sleep(5) shepherd_compose = '''version: "3.8" services: shepherd: image: containrrr/shepherd:latest environment: - SLEEP_TIME=24h - BLACKLIST_SERVICES=nginx-proxy-manager_app nginx-proxy-manager_backup - UPDATE_OPTIONS=--with-registry-auth - ROLLBACK_FAILURE=true - TZ=America/New_York volumes: - /var/run/docker.sock:/var/run/docker.sock:ro deploy: mode: replicated replicas: 1 placement: constraints: - node.role == manager restart_policy: condition: on-failure ''' sftp = c.open_sftp() with sftp.file('/tmp/shepherd_compose.yml', 'w') as f: f.write(shepherd_compose) sftp.close() print("\n=== 2. Deploying Swarm-Native Shepherd Stack ===") run("docker stack deploy -c /tmp/shepherd_compose.yml shepherd") time.sleep(6) run("docker stack ls") run("docker stack ps shepherd") run("docker service logs --tail 20 $(docker service ls -q -f name=shepherd) 2>/dev/null || true") c.close() print("\n=== Shepherd Deployment Complete ===")