#!/usr/bin/env bash # ───────────────────────────────────────────────────────────────────────────── # Деплой anti-plagiarism. # # Запускается Gitea Actions runner'ом в host-режиме прямо на app-хосте 1.32 # (см. .gitea/workflows/deploy.yml). Ожидает: # - cwd = свежий чекаут репозитория; # - переменную окружения PVE_PASSWORD (секрет Gitea) для доступа к Proxmox-хосту, # через который статика кладётся в CT 102 (reverse-proxy nginx). # # Что делает: # 1. Синхронизирует код (services/ + scripts/) в /home/user/anti-plagiarism, # НЕ трогая .env и локально-правленый docker-compose.prod.yml. # 2. Пересобирает и перезапускает бэкенд-сервисы (api + воркеры). # 3. Применяет миграции БД. # 4. Собирает фронтенд (npm build) в статику. # 5. Выкладывает статику в /var/www/academic на CT 102 (с бэкапом + reload nginx). # ───────────────────────────────────────────────────────────────────────────── set -euo pipefail APP=/home/user/anti-plagiarism SRC="$(pwd)" PVE_HOST=192.168.20.254 # Proxmox-хост, через pct exec которого живёт CT 102 COMPOSE="docker compose -f docker-compose.prod.yml" BACKEND_SERVICES="api worker-gpu worker-indexer worker-notifier worker-gost" echo "==> [1/5] Синхронизация кода в $APP (сохраняя .env и compose)" rsync -a \ --exclude='__pycache__/' --exclude='*.pyc' --exclude='.pytest_cache/' \ --exclude='node_modules/' --exclude='dist/' \ "$SRC/services" "$SRC/scripts" "$APP/" echo "==> [2/5] Пересборка и перезапуск бэкенд-сервисов" cd "$APP" # shellcheck disable=SC2086 $COMPOSE up -d --build $BACKEND_SERVICES echo "==> [3/5] Миграции БД (с ретраем, пока api поднимается)" for i in $(seq 1 10); do if $COMPOSE exec -T api alembic upgrade head; then break fi echo " api ещё не готов, повтор $i/10..." sleep 5 done echo "==> [4/5] Сборка фронтенда" docker run --rm -v "$APP/services/frontend":/app -w /app node:20-slim \ sh -c "npm install --no-audit --no-fund --loglevel=error && npm run build" echo "==> [5/5] Выкладка статики на CT 102 (через $PVE_HOST)" cd "$APP/services/frontend/dist" tar czf /tmp/academic-dist.tgz . export SSHPASS="${PVE_PASSWORD:?PVE_PASSWORD не задан}" SSHOPT="-o StrictHostKeyChecking=no -o ConnectTimeout=10" # shellcheck disable=SC2086 sshpass -e scp $SSHOPT /tmp/academic-dist.tgz "root@${PVE_HOST}:/tmp/academic-dist.tgz" # shellcheck disable=SC2086 sshpass -e ssh $SSHOPT "root@${PVE_HOST}" 'bash -s' <<'REMOTE' set -e pct push 102 /tmp/academic-dist.tgz /tmp/academic-dist.tgz pct exec 102 -- bash -c ' set -e cd /var/www cp -a academic "academic.bak.$(date +%s)" cd academic rm -rf assets index.html tar xzf /tmp/academic-dist.tgz chown -R 1000:1000 . nginx -t && nginx -s reload ' rm -f /tmp/academic-dist.tgz REMOTE rm -f /tmp/academic-dist.tgz echo "==> Деплой завершён успешно"