feat: multi-target deploy script supporting Pi and Beta VM
This commit is contained in:
@@ -1,45 +1,119 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# ============================================================
|
||||||
|
# Backspace — Quick Deploy Script
|
||||||
|
# ============================================================
|
||||||
|
# Syncs code and rebuilds on remote server(s).
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./deploy.sh Deploy to both (default)
|
||||||
|
# ./deploy.sh pi Deploy to Pi (nova.ddns.net)
|
||||||
|
# ./deploy.sh vm Deploy to VM (orbit.ddns.net)
|
||||||
|
# ./deploy.sh all Deploy to both
|
||||||
|
# ./deploy.sh --local Force Pi via LAN IP
|
||||||
|
# ./deploy.sh --remote Force Pi via public DNS
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
# Configuration
|
# ── Targets ─────────────────────────────────────────────────
|
||||||
LOCAL_IP="192.168.1.10"
|
|
||||||
REMOTE_HOST="nova.ddns.net"
|
|
||||||
PI_USER="youruser"
|
PI_USER="youruser"
|
||||||
REMOTE_PATH="~/backspace"
|
|
||||||
|
|
||||||
# Host selection: --remote / -r | --local / -l | auto-detect (default)
|
declare -A TARGETS=(
|
||||||
if [[ "$1" == "--remote" || "$1" == "-r" ]]; then
|
[pi_local]="192.168.1.10"
|
||||||
PI_HOST="$REMOTE_HOST"
|
[pi_remote]="nova.ddns.net"
|
||||||
elif [[ "$1" == "--local" || "$1" == "-l" ]]; then
|
[pi_path]="~/backspace"
|
||||||
PI_HOST="$LOCAL_IP"
|
[beta_host]="orbit.ddns.net"
|
||||||
else
|
[beta_path]="~/backspace"
|
||||||
if ping -c1 -W2 "$LOCAL_IP" &>/dev/null; then
|
)
|
||||||
PI_HOST="$LOCAL_IP"
|
|
||||||
else
|
|
||||||
PI_HOST="$REMOTE_HOST"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "🎯 Target: $PI_USER@$PI_HOST"
|
# ── Rsync excludes ──────────────────────────────────────────
|
||||||
|
|
||||||
# 0. Ensure remote directory exists
|
EXCLUDES=(
|
||||||
echo "📁 Preparing remote directory on Pi..."
|
--exclude='node_modules'
|
||||||
ssh "$PI_USER@$PI_HOST" "mkdir -p $REMOTE_PATH"
|
--exclude='.git'
|
||||||
|
--exclude='.env'
|
||||||
|
--exclude='.env.local'
|
||||||
|
--exclude='packages/*/node_modules'
|
||||||
|
--exclude='packages/web/dist'
|
||||||
|
--exclude='data'
|
||||||
|
--exclude='livekit.yaml'
|
||||||
|
--exclude='.DS_Store'
|
||||||
|
--exclude='Gemini Starter.rtf'
|
||||||
|
--exclude='System Prompt.rtf'
|
||||||
|
)
|
||||||
|
|
||||||
# 1. Sync files via rsync
|
# ── Deploy function ─────────────────────────────────────────
|
||||||
echo "🚀 Syncing files to Pi..."
|
|
||||||
|
deploy() {
|
||||||
|
local name="$1"
|
||||||
|
local host="$2"
|
||||||
|
local path="$3"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══ Deploying to $name ($host) ═══"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Ensure remote directory exists
|
||||||
|
echo " [1/3] Preparing remote directory..."
|
||||||
|
ssh "$PI_USER@$host" "mkdir -p $path"
|
||||||
|
|
||||||
|
# Sync files
|
||||||
|
echo " [2/3] Syncing files..."
|
||||||
rsync -avz --delete \
|
rsync -avz --delete \
|
||||||
--exclude='node_modules' \
|
"${EXCLUDES[@]}" \
|
||||||
--exclude='.git' \
|
./ "$PI_USER@$host:$path"
|
||||||
--exclude='.env.local' \
|
|
||||||
--exclude='packages/*/node_modules' \
|
|
||||||
--exclude='packages/web/dist' \
|
|
||||||
--exclude='data' \
|
|
||||||
--exclude='.DS_Store' \
|
|
||||||
./ "$PI_USER@$PI_HOST:$REMOTE_PATH"
|
|
||||||
|
|
||||||
# 2. Trigger Docker Compose directly on the Pi via SSH
|
# Rebuild
|
||||||
echo "🚢 Triggering build and deploy on Pi hardware..."
|
echo " [3/3] Building and restarting..."
|
||||||
ssh "$PI_USER@$PI_HOST" "cd $REMOTE_PATH && docker compose up -d --build"
|
ssh "$PI_USER@$host" "cd $path && docker compose up -d --build"
|
||||||
|
|
||||||
echo "✅ Deployment command sent to Pi!"
|
echo ""
|
||||||
|
echo " Done: $name"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Resolve Pi host (LAN or WAN) ───────────────────────────
|
||||||
|
|
||||||
|
resolve_pi_host() {
|
||||||
|
if ping -c1 -W2 "${TARGETS[pi_local]}" &>/dev/null; then
|
||||||
|
echo "${TARGETS[pi_local]}"
|
||||||
|
else
|
||||||
|
echo "${TARGETS[pi_remote]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Parse arguments ─────────────────────────────────────────
|
||||||
|
|
||||||
|
TARGET="${1:-all}"
|
||||||
|
|
||||||
|
case "$TARGET" in
|
||||||
|
pi|--local|--remote|-l|-r)
|
||||||
|
if [[ "$TARGET" == "--local" || "$TARGET" == "-l" ]]; then
|
||||||
|
PI_HOST="${TARGETS[pi_local]}"
|
||||||
|
elif [[ "$TARGET" == "--remote" || "$TARGET" == "-r" ]]; then
|
||||||
|
PI_HOST="${TARGETS[pi_remote]}"
|
||||||
|
else
|
||||||
|
PI_HOST=$(resolve_pi_host)
|
||||||
|
fi
|
||||||
|
deploy "Pi" "$PI_HOST" "${TARGETS[pi_path]}"
|
||||||
|
;;
|
||||||
|
|
||||||
|
vm|beta|orbit)
|
||||||
|
deploy "Beta VM" "${TARGETS[beta_host]}" "${TARGETS[beta_path]}"
|
||||||
|
;;
|
||||||
|
|
||||||
|
all|both)
|
||||||
|
PI_HOST=$(resolve_pi_host)
|
||||||
|
deploy "Pi" "$PI_HOST" "${TARGETS[pi_path]}"
|
||||||
|
deploy "Beta VM" "${TARGETS[beta_host]}" "${TARGETS[beta_path]}"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: ./deploy.sh [pi|vm|all|--local|--remote]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Deployment complete."
|
||||||
|
|||||||
Reference in New Issue
Block a user