#!/usr/bin/env bash # Sync local Nexus working tree to production host (no Gitea push/pull). # Transfer via tar|ssh; remote ownership auto-detected (www:www on BT, else deploy path owner). # # Usage: # bash deploy/rsync-local-to-server.sh # NEXUS_DEPLOY_PATH=/opt/nexus bash deploy/rsync-local-to-server.sh set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" SECRETS="${ROOT}/deploy/nexus-1panel.secrets.sh" if [[ -f "$SECRETS" ]]; then # shellcheck disable=SC1090 source "$SECRETS" fi NEXUS_SSH_HOST="${NEXUS_SSH:-nexus}" SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=15) if [[ -n "${NEXUS_SSH_KEY:-}" ]]; then SSH_OPTS+=(-i "${NEXUS_SSH_KEY}") fi ssh_cmd() { ssh "${SSH_OPTS[@]}" "${NEXUS_SSH_HOST}" "$@"; } if ! ssh_cmd "echo SSH OK" >/dev/null 2>&1; then echo "ERROR: Cannot SSH to ${NEXUS_SSH_HOST}" >&2 exit 1 fi DEPLOY_PATH="${NEXUS_DEPLOY_PATH:-}" if [[ -z "$DEPLOY_PATH" ]]; then DEPLOY_PATH="$(ssh_cmd 'for d in /opt/nexus /www/wwwroot/api.synaglobal.vip; do [[ -d "$d/server" ]] && echo "$d" && exit 0; done; echo /opt/nexus')" fi resolve_deploy_chown() { if [[ -n "${NEXUS_DEPLOY_CHOWN:-}" ]]; then echo "${NEXUS_DEPLOY_CHOWN}" return fi if ssh_cmd "getent passwd www >/dev/null 2>&1"; then echo "www:www" return fi ssh_cmd "stat -c '%U:%G' '${DEPLOY_PATH}'" 2>/dev/null || echo "azureuser:azureuser" } DEPLOY_CHOWN="$(resolve_deploy_chown)" echo "═══ Nexus local → server sync ═══" echo "SSH target: ${NEXUS_SSH_HOST}" echo "Remote path: ${DEPLOY_PATH}" echo "Owner: ${DEPLOY_CHOWN}" TAR_EXCLUDES=( --exclude='.git' --exclude='.env' --exclude='.env.*' --exclude='SECRETS.md' --exclude='deploy/nexus-1panel.secrets.sh' --exclude='docker/.env.prod' --exclude='web/data' --exclude='frontend/node_modules' --exclude='frontend-v2/node_modules' --exclude='node_modules' --exclude='.venv' --exclude='.venv-*' --exclude='venv' --exclude='__pycache__' --exclude='.pytest_cache' --exclude='.ruff_cache' --exclude='.cursor' --exclude='.playwright-mcp' --exclude='.install_locked' --exclude='.install_state.json' --exclude='web/app/assets' --exclude='tmp' --exclude='2025.2' --exclude='=2025.2' --exclude='*.bak-' --exclude='frontend/test-results' --exclude='frontend/e2e/.auth' ) echo "▶ tar stream → ${DEPLOY_PATH} ..." tar -C "${ROOT}" -czf - "${TAR_EXCLUDES[@]}" . | \ ssh "${SSH_OPTS[@]}" "${NEXUS_SSH_HOST}" "sudo tar -xzf - -C '${DEPLOY_PATH}'" echo "▶ chown ${DEPLOY_CHOWN} (skip docker/.env.prod, web/data, .env) ..." ssh_cmd "sudo bash -s" <