Files
backspace/deploy.sh
T
Jannis Braun 2999ca95a0 fix: prevent stale voice sidebar after multi-session identity collision
When a second browser joins voice, LiveKit disconnects the first browser
via identity collision. The first browser's leaveVoice() was optimistically
removing the user from voiceUsers, but the user is still in voice from
the other session. Add handleForceDisconnect() that clears local connection
state without touching voiceUsers, keeping the sidebar accurate.

Also fix deploy.sh to clean up stale renamed containers from failed recreates.
2026-03-09 23:48:44 +01:00

119 lines
3.3 KiB
Bash
Executable File

#!/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")"
# ── Targets ─────────────────────────────────────────────────
PI_USER="youruser"
PI_LOCAL="192.168.1.10"
PI_REMOTE="nova.ddns.net"
PI_PATH="~/backspace"
BETA_HOST="orbit.ddns.net"
BETA_PATH="~/backspace"
# ── 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..."
# Clean up stale renamed containers left by failed recreates (e.g. "d420a6c00439_backspace")
ssh "$PI_USER@$host" "cd $path && docker rm -f \$(docker ps -aq --filter 'name=_backspace' 2>/dev/null) 2>/dev/null; docker compose up -d --build"
echo ""
echo " Done: $name"
}
# ── Resolve Pi host (LAN or WAN) ───────────────────────────
resolve_pi_host() {
if ping -c1 -W2 "$PI_LOCAL" &>/dev/null; then
echo "$PI_LOCAL"
else
echo "$PI_REMOTE"
fi
}
# ── Parse arguments ─────────────────────────────────────────
TARGET="${1:-all}"
case "$TARGET" in
pi|--local|--remote|-l|-r)
if [[ "$TARGET" == "--local" || "$TARGET" == "-l" ]]; then
PI_HOST="$PI_LOCAL"
elif [[ "$TARGET" == "--remote" || "$TARGET" == "-r" ]]; then
PI_HOST="$PI_REMOTE"
else
PI_HOST=$(resolve_pi_host)
fi
deploy "Pi" "$PI_HOST" "$PI_PATH"
;;
vm|beta|orbit)
deploy "Beta VM" "$BETA_HOST" "$BETA_PATH"
;;
all|both)
PI_HOST=$(resolve_pi_host)
deploy "Pi" "$PI_HOST" "$PI_PATH"
deploy "Beta VM" "$BETA_HOST" "$BETA_PATH"
;;
*)
echo "Usage: ./deploy.sh [pi|vm|all|--local|--remote]"
exit 1
;;
esac
echo ""
echo "Deployment complete."