|
|
|
|
@@ -25,11 +25,14 @@ ARCHIPELAGO_PASSWORD="${ARCHIPELAGO_PASSWORD:-archipelago}"
|
|
|
|
|
# Force password auth when using sshpass (avoids "Permission denied" from SSH key mismatch)
|
|
|
|
|
SSH_OPTS="-o StrictHostKeyChecking=no -o PreferredAuthentications=password -o PubkeyAuthentication=no"
|
|
|
|
|
|
|
|
|
|
DEPLOY_START=$(date +%s)
|
|
|
|
|
timestamp() { echo "[$(date +%H:%M:%S)]"; }
|
|
|
|
|
|
|
|
|
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
|
|
|
|
echo "║ Deploying to Archipelago Target ║"
|
|
|
|
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
|
|
|
|
echo ""
|
|
|
|
|
echo "Target: $TARGET_HOST"
|
|
|
|
|
echo "$(timestamp) Target: $TARGET_HOST"
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
# Parse arguments
|
|
|
|
|
@@ -70,7 +73,7 @@ if [ "$BOTH" = true ]; then
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Sync code
|
|
|
|
|
echo "📦 Syncing code..."
|
|
|
|
|
echo "$(timestamp) 📦 Syncing code..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" rsync -avz --delete \
|
|
|
|
|
-e "ssh $SSH_OPTS" \
|
|
|
|
|
--exclude 'node_modules' \
|
|
|
|
|
@@ -89,33 +92,33 @@ fi
|
|
|
|
|
|
|
|
|
|
# Build on target
|
|
|
|
|
echo ""
|
|
|
|
|
echo "🔨 Building on target..."
|
|
|
|
|
echo "$(timestamp) 🔨 Building on target..."
|
|
|
|
|
|
|
|
|
|
# Frontend
|
|
|
|
|
echo " Building frontend..."
|
|
|
|
|
echo "$(timestamp) Building frontend (vue-tsc + vite)..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "cd $TARGET_DIR/neode-ui && npm install --silent && npm run build" 2>&1 | sed 's/^/ /'
|
|
|
|
|
|
|
|
|
|
# Backend (if Rust is installed)
|
|
|
|
|
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "source ~/.cargo/env 2>/dev/null && command -v cargo" >/dev/null 2>&1; then
|
|
|
|
|
echo " Building backend..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "source ~/.cargo/env && cd $TARGET_DIR/core && cargo build --release 2>&1" | tail -10 | sed 's/^/ /'
|
|
|
|
|
echo "$(timestamp) Building backend (Rust release — this takes 1-2 min)..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "source ~/.cargo/env && cd $TARGET_DIR/core && cargo build --release 2>&1" | sed 's/^/ /'
|
|
|
|
|
else
|
|
|
|
|
echo " ⚠️ Rust not installed on target, skipping backend build"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ "$LIVE" = true ]; then
|
|
|
|
|
echo ""
|
|
|
|
|
echo "🚀 Deploying to live system..."
|
|
|
|
|
|
|
|
|
|
echo "$(timestamp) 🚀 Deploying to live system..."
|
|
|
|
|
|
|
|
|
|
# Deploy backend (check if binary exists)
|
|
|
|
|
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "[ -f $TARGET_DIR/core/target/release/archipelago ]" 2>/dev/null; then
|
|
|
|
|
echo " Deploying backend binary..."
|
|
|
|
|
echo "$(timestamp) Deploying backend binary..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo systemctl stop archipelago"
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo cp $TARGET_DIR/core/target/release/archipelago /usr/local/bin/"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Deploy frontend
|
|
|
|
|
echo " Deploying frontend..."
|
|
|
|
|
echo "$(timestamp) Deploying frontend..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo rm -rf /opt/archipelago/web-ui/*"
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo cp -r $TARGET_DIR/web/dist/neode-ui/* /opt/archipelago/web-ui/"
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui"
|
|
|
|
|
@@ -157,15 +160,15 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Restart services
|
|
|
|
|
echo " Restarting services..."
|
|
|
|
|
echo "$(timestamp) Restarting services..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo systemctl start archipelago && sudo systemctl restart nginx"
|
|
|
|
|
|
|
|
|
|
# Set up HTTPS for PWA installability (browsers require secure context)
|
|
|
|
|
echo " Setting up HTTPS for PWA install..."
|
|
|
|
|
echo "$(timestamp) Setting up HTTPS for PWA install..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo bash $TARGET_DIR/scripts/setup-https-dev.sh" 2>&1 | sed 's/^/ /' || true
|
|
|
|
|
|
|
|
|
|
# Rebuild and recreate LND UI container (port 8081 so Launch from UI and http://host:8081 both work)
|
|
|
|
|
echo " Rebuilding LND UI..."
|
|
|
|
|
echo "$(timestamp) Rebuilding LND UI..."
|
|
|
|
|
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "cd $TARGET_DIR/docker/lnd-ui && (command -v podman >/dev/null 2>&1 && sudo podman build --no-cache -t lnd-ui:latest . || sudo docker build --no-cache -t lnd-ui:latest .)" 2>&1 | tail -12 | sed 's/^/ /'; then
|
|
|
|
|
echo " Recreating LND UI container (port 8081)..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" '
|
|
|
|
|
@@ -179,7 +182,7 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Rebuild and recreate Electrs UI container (port 50002)
|
|
|
|
|
echo " Rebuilding Electrs UI..."
|
|
|
|
|
echo "$(timestamp) Rebuilding Electrs UI..."
|
|
|
|
|
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "cd $TARGET_DIR/docker/electrs-ui && (command -v podman >/dev/null 2>&1 && sudo podman build --no-cache -t electrs-ui:latest . || sudo docker build --no-cache -t electrs-ui:latest .)" 2>&1 | tail -12 | sed 's/^/ /'; then
|
|
|
|
|
echo " Recreating Electrs UI container (port 50002, host network)..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" '
|
|
|
|
|
@@ -194,7 +197,7 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
|
|
|
|
|
# Bitcoin Knots: required for Mempool, Electrs, BTCPay, Fedimint
|
|
|
|
|
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
|
|
|
|
|
echo " Ensuring Bitcoin Knots (required for Electrs/Mempool)..."
|
|
|
|
|
echo "$(timestamp) Ensuring Bitcoin Knots..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
|
|
|
|
|
DOCKER=podman
|
|
|
|
|
command -v podman >/dev/null 2>&1 || DOCKER=docker
|
|
|
|
|
@@ -218,7 +221,7 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
" 2>&1 | sed 's/^/ /' || true
|
|
|
|
|
|
|
|
|
|
# Fix Mempool: clean duplicates, ensure full stack - mysql, backend (8999), frontend (4080)
|
|
|
|
|
echo " Fixing Mempool stack (host=$TARGET_IP)..."
|
|
|
|
|
echo "$(timestamp) Fixing Mempool stack..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
|
|
|
|
|
DOCKER=podman
|
|
|
|
|
command -v podman >/dev/null 2>&1 || DOCKER=docker
|
|
|
|
|
@@ -322,7 +325,7 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
" 2>&1 | sed 's/^/ /' || true
|
|
|
|
|
|
|
|
|
|
# Fix BTCPay Server: requires PostgreSQL + NBXplorer (BTCPay needs NBXplorer for block indexing)
|
|
|
|
|
echo " Fixing BTCPay Server stack..."
|
|
|
|
|
echo "$(timestamp) Fixing BTCPay Server stack..."
|
|
|
|
|
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
|
|
|
|
|
DOCKER=podman
|
|
|
|
|
@@ -397,7 +400,7 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
" 2>&1 | sed 's/^/ /' || true
|
|
|
|
|
|
|
|
|
|
# Ensure Immich stack (postgres + redis + server) - creates if missing
|
|
|
|
|
echo " Ensuring Immich stack (port 2283)..."
|
|
|
|
|
echo "$(timestamp) Ensuring Immich stack..."
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
|
|
|
|
|
DOCKER=podman
|
|
|
|
|
command -v podman >/dev/null 2>&1 || DOCKER=docker
|
|
|
|
|
@@ -439,7 +442,7 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
" 2>&1 | sed 's/^/ /' || true
|
|
|
|
|
|
|
|
|
|
# Tor: global hidden services - each service gets its own .onion address
|
|
|
|
|
echo " Setting up Tor (hidden services for each app)..."
|
|
|
|
|
echo "$(timestamp) Setting up Tor..."
|
|
|
|
|
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
|
|
|
|
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
|
|
|
|
|
DOCKER=podman
|
|
|
|
|
@@ -505,7 +508,7 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
" 2>&1 | sed 's/^/ /' || true
|
|
|
|
|
|
|
|
|
|
# Recreate Fedimint with FM_API_URL for Guardian UI (fixes "Api URL must be configured")
|
|
|
|
|
echo " Fixing Fedimint API URL..."
|
|
|
|
|
echo "$(timestamp) Fixing Fedimint API URL..."
|
|
|
|
|
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
|
|
|
|
|
TIMEOUT_CMD=""
|
|
|
|
|
command -v timeout >/dev/null 2>&1 && TIMEOUT_CMD="timeout 90"
|
|
|
|
|
@@ -535,8 +538,10 @@ if [ "$LIVE" = true ]; then
|
|
|
|
|
done
|
|
|
|
|
" 2>&1 | sed 's/^/ /') || echo " (Fedimint fix timed out or skipped - run manually if needed)"
|
|
|
|
|
|
|
|
|
|
DEPLOY_END=$(date +%s)
|
|
|
|
|
DEPLOY_ELAPSED=$((DEPLOY_END - DEPLOY_START))
|
|
|
|
|
echo ""
|
|
|
|
|
echo "✅ Deployed to live system!"
|
|
|
|
|
echo "$(timestamp) ✅ Deployed to live system! (${DEPLOY_ELAPSED}s total)"
|
|
|
|
|
echo " Backend: $(sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" 'sudo systemctl is-active archipelago')"
|
|
|
|
|
echo " Web UI: http://$(echo $TARGET_HOST | cut -d@ -f2)"
|
|
|
|
|
echo " PWA install: https://$(echo $TARGET_HOST | cut -d@ -f2) (use HTTPS, accept cert once, then Install app)"
|
|
|
|
|
|