code-review-agent/redeploy-ubuntu.sh
Primakov Alexandr Alexandrovich 493a14e2c8 Enhance deployment documentation and add redeploy guide
- Updated `README.md` to include instructions for the new `redeploy-ubuntu.sh` script and added a link to the new `REDEPLOY_GUIDE.md`.
- Created `REDEPLOY_GUIDE.md` detailing the redeployment process, including backup creation, code updates, and troubleshooting steps.
- Introduced `redeploy-hint.md` for GitHub Actions automation example, outlining setup for automatic redeployment on push events.
- Improved documentation structure for better navigation and clarity.
2025-10-13 00:15:47 +03:00

306 lines
11 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
###############################################################################
# AI Code Review Agent - Redeploy Script для Ubuntu/Debian
###############################################################################
#
# Этот скрипт обновляет и перезапускает AI Review Agent на сервере
#
# Использование:
# sudo bash redeploy-ubuntu.sh
# или
# sudo ./redeploy-ubuntu.sh
#
###############################################################################
# Проверка, что используется bash
if [ -z "$BASH_VERSION" ]; then
echo "ERROR: Этот скрипт требует bash. Запустите: sudo bash redeploy-ubuntu.sh"
exit 1
fi
set -e # Выход при ошибке
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Функции для красивого вывода
print_step() {
echo -e "\n${BLUE}[STEP $1/$2]${NC} $3"
}
print_success() {
echo -e "${GREEN}[OK]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_header() {
echo -e "\n${GREEN}╔════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ AI Review Agent - Redeploy ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════╝${NC}\n"
}
# Проверка прав root
if [ "$EUID" -ne 0 ]; then
print_error "Запустите скрипт с sudo"
exit 1
fi
print_header
# Определить пользователя, который запустил sudo
REAL_USER="${SUDO_USER:-$USER}"
if [ "$REAL_USER" = "root" ]; then
print_error "Не запускайте этот скрипт напрямую из-под root. Используйте sudo от обычного пользователя."
exit 1
fi
# Определить директорию установки
# Если скрипт запущен из текущей директории, используем её
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="${SCRIPT_DIR}"
SERVICE_NAME="ai-review"
# Проверить, что это похоже на директорию AI Review
if [ ! -d "$INSTALL_DIR/backend" ] || [ ! -d "$INSTALL_DIR/frontend" ]; then
print_error "Не найдены директории backend или frontend"
print_warning "Запустите скрипт из корня проекта AI Review Agent"
exit 1
fi
# Проверка, что сервис установлен
if ! systemctl list-unit-files | grep -q "^${SERVICE_NAME}.service"; then
print_warning "Сервис ${SERVICE_NAME} не найден в systemd"
print_warning "Продолжаем без управления сервисом..."
SERVICE_EXISTS=false
else
SERVICE_EXISTS=true
fi
cd "$INSTALL_DIR"
print_warning "Рабочая директория: $INSTALL_DIR"
# ============================================================================
# Шаг 1: Остановка сервиса
# ============================================================================
print_step 1 7 "Остановка сервиса..."
if [ "$SERVICE_EXISTS" = true ]; then
systemctl stop "$SERVICE_NAME" || print_warning "Не удалось остановить сервис"
print_success "Сервис остановлен"
else
print_warning "Сервис не установлен, пропускаем остановку"
fi
# ============================================================================
# Шаг 2: Создание backup
# ============================================================================
print_step 2 7 "Создание backup..."
BACKUP_DIR="$INSTALL_DIR/backups"
mkdir -p "$BACKUP_DIR" || print_warning "Не удалось создать директорию backup"
BACKUP_NAME="backup-$(date +%Y%m%d-%H%M%S)"
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
# Backup базы данных
if [ -f "$INSTALL_DIR/backend/review.db" ]; then
mkdir -p "$BACKUP_PATH"
cp "$INSTALL_DIR/backend/review.db" "$BACKUP_PATH/" 2>/dev/null || {
print_warning "Не удалось создать backup БД"
}
if [ -f "$BACKUP_PATH/review.db" ]; then
print_success "База данных сохранена в $BACKUP_PATH"
fi
else
print_warning "База данных не найдена, пропускаем backup"
fi
# ============================================================================
# Шаг 3: Обновление кода
# ============================================================================
print_step 3 7 "Обновление кода..."
# Проверка, что это git репозиторий
if [ -d ".git" ]; then
# Сохранить изменения в .env если есть
if [ -f "backend/.env" ]; then
cp backend/.env /tmp/ai-review-env-backup 2>/dev/null || true
fi
# Получить текущую ветку
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
print_warning "Текущая ветка: $CURRENT_BRANCH"
# Обновить код
sudo -u "$REAL_USER" git fetch --all 2>/dev/null || print_warning "Не удалось обновить из git"
sudo -u "$REAL_USER" git pull origin "$CURRENT_BRANCH" 2>/dev/null || print_warning "Не удалось выполнить git pull"
# Восстановить .env
if [ -f "/tmp/ai-review-env-backup" ]; then
cp /tmp/ai-review-env-backup backend/.env 2>/dev/null || true
rm /tmp/ai-review-env-backup 2>/dev/null || true
fi
print_success "Код обновлен"
else
print_warning "Не git репозиторий, пропускаем обновление кода"
print_warning "Предполагается, что код уже обновлен вручную"
sleep 2
fi
# ============================================================================
# Шаг 4: Обновление зависимостей Backend
# ============================================================================
print_step 4 7 "Обновление зависимостей Backend..."
cd backend
# Активировать venv и установить зависимости
if [ -d "venv" ]; then
sudo -u "$REAL_USER" bash -c "
source venv/bin/activate
pip install --upgrade pip > /dev/null 2>&1
pip install -r requirements.txt > /dev/null 2>&1
"
print_success "Зависимости Backend обновлены"
else
print_error "Virtual environment не найден"
exit 1
fi
# ============================================================================
# Шаг 5: Применение миграций БД
# ============================================================================
print_step 5 7 "Применение миграций БД..."
if [ -f "migrate.py" ]; then
sudo -u "$REAL_USER" bash -c "
source venv/bin/activate
python migrate.py
" 2>&1 | grep -E "(✅|Таблицы|создан)" || true
print_success "Миграции применены"
else
print_warning "Скрипт миграции не найден, пропускаем"
fi
cd ..
# ============================================================================
# Шаг 6: Сборка Frontend
# ============================================================================
print_step 6 7 "Сборка Frontend..."
cd frontend
# Проверить наличие Node.js
if ! command -v node &> /dev/null; then
print_error "Node.js не установлен"
exit 1
fi
# Установить зависимости если нужно
if [ ! -d "node_modules" ]; then
print_warning "Установка зависимостей..."
sudo -u "$REAL_USER" npm install > /dev/null 2>&1
fi
# Создать .env.production для правильных URL
cat > .env.production << EOF
VITE_API_URL=/api
VITE_WS_URL=
EOF
# Собрать frontend
sudo -u "$REAL_USER" npm run build 2>&1 | grep -E "(✓|built in)" || true
print_success "Frontend собран"
# Проверить, что build создан
if [ ! -d "../backend/public" ]; then
print_error "Frontend не собрался в backend/public"
exit 1
fi
cd ..
# ============================================================================
# Шаг 7: Запуск сервиса
# ============================================================================
print_step 7 7 "Запуск сервиса..."
# Установить правильные права
chown -R "$REAL_USER:$REAL_USER" "$INSTALL_DIR" 2>/dev/null || print_warning "Не удалось установить права"
if [ "$SERVICE_EXISTS" = true ]; then
# Запустить сервис
systemctl start "$SERVICE_NAME"
# Подождать немного
sleep 2
# Проверить статус
if systemctl is-active --quiet "$SERVICE_NAME"; then
print_success "Сервис запущен"
else
print_error "Сервис не запустился"
echo ""
echo "Логи сервиса:"
journalctl -u "$SERVICE_NAME" -n 20 --no-pager
exit 1
fi
else
print_warning "Сервис не установлен в systemd"
print_warning "Запустите вручную: cd backend && source venv/bin/activate && uvicorn app.main:app --host 0.0.0.0 --port 8000"
fi
# ============================================================================
# Финал
# ============================================================================
echo ""
echo -e "${GREEN}╔════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Redeploy завершен успешно! ✅ ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════╝${NC}"
echo ""
# Получить IP адрес
SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
if [ -z "$SERVER_IP" ]; then
SERVER_IP="localhost"
fi
echo "Сервис: http://${SERVER_IP}:8000"
if [ "$SERVICE_EXISTS" = true ]; then
echo "Статус: systemctl status $SERVICE_NAME"
echo "Логи: journalctl -u $SERVICE_NAME -f"
else
echo "Запуск: cd $INSTALL_DIR/backend && source venv/bin/activate && uvicorn app.main:app --host 0.0.0.0 --port 8000"
fi
echo ""
if [ -f "$BACKUP_PATH/review.db" ]; then
echo "Backup создан: $BACKUP_PATH"
echo ""
echo -e "${YELLOW}Для отката к предыдущей версии:${NC}"
echo " 1. Остановите сервис"
if [ -d ".git" ]; then
echo " 2. Восстановите БД: sudo cp $BACKUP_PATH/review.db $INSTALL_DIR/backend/"
echo " 3. Откатите git: cd $INSTALL_DIR && git reset --hard HEAD~1"
echo " 4. Запустите redeploy снова: cd $INSTALL_DIR && sudo bash redeploy-ubuntu.sh"
else
echo " 2. Восстановите БД: sudo cp $BACKUP_PATH/review.db $INSTALL_DIR/backend/"
echo " 3. Восстановите старые файлы вручную"
fi
fi
echo ""