#!/bin/bash # Deploy/stop/restart/status tour-comfy project on the tour machine. # # Usage: # ./deploy_api.sh # ./deploy_api.sh deploy tour|hubby|all # ./deploy_api.sh stop tour|hubby|all # ./deploy_api.sh restart tour|hubby|all # ./deploy_api.sh status tour|hubby|all set -euo pipefail SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" ACTION="${1:-deploy}" TARGET="${2:-tour}" REMOTES=() TOUR_SPEC="tour@192.168.1.160:/media/tour/APPS/comfyui/api" HUBBY_SPEC="hubby@192.168.1.171:/home/hubby/comfyui/api" case "$TARGET" in tour) REMOTES=("$TOUR_SPEC") ;; hubby) REMOTES=("$HUBBY_SPEC") ;; all) REMOTES=("$TOUR_SPEC" "$HUBBY_SPEC") ;; *) echo "Usage: $0 [deploy|stop|restart|status] [tour|hubby|all]" exit 1 ;; esac print_header() { local title="$1" echo echo "============================================================" echo "$title" echo "============================================================" } stop_one() { local REMOTE_SPEC="$1" local REMOTE="${REMOTE_SPEC%%:*}" local REMOTE_DIR="${REMOTE_SPEC##*:}" print_header "Stopping services on $REMOTE" ssh "$REMOTE" "sudo bash $REMOTE_DIR/stop.sh" } deploy_one() { local REMOTE_SPEC="$1" local REMOTE="${REMOTE_SPEC%%:*}" local REMOTE_DIR="${REMOTE_SPEC##*:}" print_header "Deploying to $REMOTE" echo "==> Creating remote directory..." ssh "$REMOTE" "mkdir -p $REMOTE_DIR" echo "==> Syncing project files..." # Ship code + config only; never the local test images, watcher data dirs, # logs, or runtime state. rsync -avz \ --exclude 'deploy_api.sh' \ --exclude '*.png' \ --exclude '*.log' \ --exclude 'processed.json' \ --exclude 'stage/' --exclude 'out/' --exclude 'output/' --exclude 'failed/' \ --exclude '__pycache__/' --exclude '*.pyc' --exclude '*.tmp' \ "$SCRIPT_DIR/" "$REMOTE:$REMOTE_DIR/" echo "==> Bootstrapping host (venv/ComfyUI/models; idempotent — first run downloads ~31GB)..." ssh "$REMOTE" "bash $REMOTE_DIR/bootstrap.sh" echo "==> Installing/refreshing systemd services..." ssh "$REMOTE" "sudo bash $REMOTE_DIR/deploy.sh" echo "==> Waiting for API startup (port 8500)..." for i in {1..60}; do if ssh "$REMOTE" "curl -fsS http://localhost:8500/health >/dev/null 2>&1"; then echo "==> API is ready" break fi if [ "$i" -eq 60 ]; then echo echo "ERROR: API failed to become healthy on $REMOTE" echo echo "Check logs with: ssh $REMOTE 'journalctl -u comfyui-api -n 50'" exit 1 fi sleep 2 done echo echo "==> Health check:" ssh "$REMOTE" "curl -s http://localhost:8500/health | python3 -m json.tool" echo echo "==> Service Status:" ssh "$REMOTE" "systemctl status comfyui-backend comfyui-api --no-pager || true" } status_one() { local REMOTE_SPEC="$1" local REMOTE="${REMOTE_SPEC%%:*}" local REMOTE_DIR="${REMOTE_SPEC##*:}" print_header "Status on $REMOTE" ssh "$REMOTE" " echo '==> Systemd Services:' systemctl status comfyui-backend comfyui-api --no-pager || true echo echo '==> Health (8500):' curl -fsS http://localhost:8500/health 2>/dev/null | python3 -m json.tool || echo 'not healthy' echo echo '==> Last 10 backend logs:' journalctl -u comfyui-backend -n 10 --no-pager echo echo '==> Last 10 API logs:' journalctl -u comfyui-api -n 10 --no-pager " } case "$ACTION" in deploy) for REMOTE in "${REMOTES[@]}"; do deploy_one "$REMOTE" done echo echo "All deployments completed successfully." ;; stop) for REMOTE in "${REMOTES[@]}"; do stop_one "$REMOTE" done echo echo "All services stopped." ;; restart) for REMOTE in "${REMOTES[@]}"; do # deploy_one already handles restart via deploy.sh deploy_one "$REMOTE" done echo echo "All services restarted successfully." ;; status) for REMOTE in "${REMOTES[@]}"; do status_one "$REMOTE" done ;; *) echo "Usage: $0 [deploy|stop|restart|status] [tour|hubby|all]" exit 1 ;; esac