feat: multi-target deploy script supporting Pi and Beta VM

This commit is contained in:
Jannis Braun
2026-03-04 00:36:45 +01:00
parent 9ae9a0f3dc
commit b44c2a7651
+107 -33
View File
@@ -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"
# ── Rsync excludes ──────────────────────────────────────────
EXCLUDES=(
--exclude='node_modules'
--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'
)
# ── Deploy function ─────────────────────────────────────────
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 \
"${EXCLUDES[@]}" \
./ "$PI_USER@$host:$path"
# Rebuild
echo " [3/3] Building and restarting..."
ssh "$PI_USER@$host" "cd $path && docker compose up -d --build"
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 else
PI_HOST="$REMOTE_HOST" echo "${TARGETS[pi_remote]}"
fi fi
fi }
echo "🎯 Target: $PI_USER@$PI_HOST" # ── Parse arguments ─────────────────────────────────────────
# 0. Ensure remote directory exists TARGET="${1:-all}"
echo "📁 Preparing remote directory on Pi..."
ssh "$PI_USER@$PI_HOST" "mkdir -p $REMOTE_PATH"
# 1. Sync files via rsync case "$TARGET" in
echo "🚀 Syncing files to Pi..." pi|--local|--remote|-l|-r)
rsync -avz --delete \ if [[ "$TARGET" == "--local" || "$TARGET" == "-l" ]]; then
--exclude='node_modules' \ PI_HOST="${TARGETS[pi_local]}"
--exclude='.git' \ elif [[ "$TARGET" == "--remote" || "$TARGET" == "-r" ]]; then
--exclude='.env.local' \ PI_HOST="${TARGETS[pi_remote]}"
--exclude='packages/*/node_modules' \ else
--exclude='packages/web/dist' \ PI_HOST=$(resolve_pi_host)
--exclude='data' \ fi
--exclude='.DS_Store' \ deploy "Pi" "$PI_HOST" "${TARGETS[pi_path]}"
./ "$PI_USER@$PI_HOST:$REMOTE_PATH" ;;
# 2. Trigger Docker Compose directly on the Pi via SSH vm|beta|orbit)
echo "🚢 Triggering build and deploy on Pi hardware..." deploy "Beta VM" "${TARGETS[beta_host]}" "${TARGETS[beta_path]}"
ssh "$PI_USER@$PI_HOST" "cd $REMOTE_PATH && docker compose up -d --build" ;;
echo "✅ Deployment command sent to Pi!" 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."