85 lines
3.9 KiB
Bash
85 lines
3.9 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# Split deploy for unstable Tailscale connections
|
||
|
|
# Each step is a separate short SSH session — no long-lived connections
|
||
|
|
set -e
|
||
|
|
TARGET="$1"
|
||
|
|
if [ -z "$TARGET" ]; then echo "Usage: $0 user@host"; exit 1; fi
|
||
|
|
|
||
|
|
SSH_KEY="${ARCHIPELAGO_SSH_KEY:-$HOME/.ssh/archipelago-deploy}"
|
||
|
|
SSH="ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=15 -o ServerAliveCountMax=4 -o ConnectTimeout=10 -i $SSH_KEY"
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
|
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||
|
|
TARGET_DIR="/home/archipelago/archy"
|
||
|
|
|
||
|
|
echo "=== Deploying to $TARGET (split mode) ==="
|
||
|
|
|
||
|
|
# Step 1: rsync code
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 1: Syncing code..."
|
||
|
|
rsync -az --delete \
|
||
|
|
--exclude='.git' --exclude='node_modules' --exclude='target/debug' \
|
||
|
|
--exclude='target/release/deps' --exclude='target/release/build' \
|
||
|
|
--exclude='target/release/.fingerprint' --exclude='target/release/incremental' \
|
||
|
|
--exclude='web/dist' --exclude='.DS_Store' \
|
||
|
|
-e "$SSH" \
|
||
|
|
"$PROJECT_DIR/" "$TARGET:$TARGET_DIR/" || { echo "rsync failed"; exit 1; }
|
||
|
|
echo " Synced."
|
||
|
|
|
||
|
|
# Step 2: Start frontend build in background on remote
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 2: Building frontend (background)..."
|
||
|
|
$SSH "$TARGET" "cd $TARGET_DIR/neode-ui && nohup bash -c 'npm install --silent 2>&1 && npm run build 2>&1' > /tmp/frontend-build.log 2>&1 &"
|
||
|
|
sleep 3
|
||
|
|
while true; do
|
||
|
|
sleep 5
|
||
|
|
status=$($SSH "$TARGET" "pgrep -f 'vite build' >/dev/null 2>&1 && echo running || (pgrep -f 'npm run build' >/dev/null 2>&1 && echo running || echo done)")
|
||
|
|
if [ "$status" = "done" ]; then break; fi
|
||
|
|
echo " still building frontend..."
|
||
|
|
done
|
||
|
|
$SSH "$TARGET" "tail -5 /tmp/frontend-build.log"
|
||
|
|
echo " Frontend built."
|
||
|
|
|
||
|
|
# Step 3: Start Rust build in background on remote
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 3: Building backend (background)..."
|
||
|
|
$SSH "$TARGET" "cd $TARGET_DIR && nohup bash -c 'source ~/.cargo/env 2>/dev/null && cd core && cargo build --release 2>&1' > /tmp/rust-build.log 2>&1 &"
|
||
|
|
sleep 3
|
||
|
|
while true; do
|
||
|
|
sleep 10
|
||
|
|
status=$($SSH "$TARGET" "pgrep -f 'cargo build' >/dev/null 2>&1 && echo running || echo done")
|
||
|
|
if [ "$status" = "done" ]; then break; fi
|
||
|
|
echo " still building backend..."
|
||
|
|
done
|
||
|
|
$SSH "$TARGET" "tail -5 /tmp/rust-build.log"
|
||
|
|
result=$($SSH "$TARGET" "[ -f $TARGET_DIR/core/target/release/archipelago ] && echo ok || echo fail")
|
||
|
|
if [ "$result" != "ok" ]; then echo " Backend build failed!"; exit 1; fi
|
||
|
|
echo " Backend built."
|
||
|
|
|
||
|
|
# Step 4: Deploy binary
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 4: Deploying binary..."
|
||
|
|
$SSH "$TARGET" "sudo systemctl stop archipelago 2>/dev/null; sudo cp $TARGET_DIR/core/target/release/archipelago /usr/local/bin/ && echo ' binary deployed'"
|
||
|
|
|
||
|
|
# Step 5: Deploy frontend
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 5: Deploying frontend..."
|
||
|
|
$SSH "$TARGET" "sudo find /opt/archipelago/web-ui -mindepth 1 -maxdepth 1 ! -name 'aiui' ! -name 'claude-login.html' -exec rm -rf {} + && sudo cp -rf $TARGET_DIR/web/dist/neode-ui/* /opt/archipelago/web-ui/ && sudo chown -R 1000:1000 /opt/archipelago/web-ui && echo ' frontend deployed'"
|
||
|
|
|
||
|
|
# Step 6: Deploy AIUI if present
|
||
|
|
AIUI_DIST="$PROJECT_DIR/../AIUI/packages/app/dist"
|
||
|
|
if [ -d "$AIUI_DIST" ]; then
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 6: Deploying AIUI..."
|
||
|
|
$SSH "$TARGET" "sudo mkdir -p /opt/archipelago/web-ui/aiui"
|
||
|
|
cd "$AIUI_DIST" && tar cf - . | $SSH "$TARGET" "sudo tar xf - -C /opt/archipelago/web-ui/aiui/"
|
||
|
|
$SSH "$TARGET" "sudo chown -R 1000:1000 /opt/archipelago/web-ui/aiui"
|
||
|
|
echo " AIUI deployed."
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Step 7: Restart services
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 7: Restarting services..."
|
||
|
|
$SSH "$TARGET" "sudo systemctl start archipelago && sudo systemctl restart nginx && echo ' services restarted'"
|
||
|
|
|
||
|
|
# Step 8: Health check
|
||
|
|
echo "[$(date +%H:%M:%S)] Step 8: Health check..."
|
||
|
|
sleep 3
|
||
|
|
IP=$(echo "$TARGET" | cut -d@ -f2)
|
||
|
|
health=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 "http://$IP/health" 2>/dev/null || echo "000")
|
||
|
|
echo " Health: $health"
|
||
|
|
|
||
|
|
echo "=== Deploy complete for $TARGET ==="
|