diff --git a/redeploy-ubuntu.sh b/redeploy-ubuntu.sh new file mode 100644 index 0000000..42daf17 --- /dev/null +++ b/redeploy-ubuntu.sh @@ -0,0 +1,264 @@ +#!/bin/bash + +############################################################################### +# AI Code Review Agent - Redeploy Script для Ubuntu/Debian +############################################################################### +# +# Этот скрипт обновляет и перезапускает AI Review Agent на сервере +# +# Использование: +# sudo ./redeploy-ubuntu.sh +# +############################################################################### + +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 + +INSTALL_DIR="/opt/ai-review" +SERVICE_NAME="ai-review" + +# Проверка, что сервис установлен +if [ ! -d "$INSTALL_DIR" ]; then + print_error "AI Review Agent не установлен в $INSTALL_DIR" + print_warning "Сначала запустите deploy-ubuntu.sh" + exit 1 +fi + +if ! systemctl list-unit-files | grep -q "^${SERVICE_NAME}.service"; then + print_error "Сервис ${SERVICE_NAME} не найден" + print_warning "Сначала запустите deploy-ubuntu.sh" + exit 1 +fi + +cd "$INSTALL_DIR" + +# ============================================================================ +# Шаг 1: Остановка сервиса +# ============================================================================ +print_step 1 7 "Остановка сервиса..." + +systemctl stop "$SERVICE_NAME" +print_success "Сервис остановлен" + +# ============================================================================ +# Шаг 2: Создание backup +# ============================================================================ +print_step 2 7 "Создание backup..." + +BACKUP_DIR="/opt/ai-review-backups" +mkdir -p "$BACKUP_DIR" +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/" + print_success "База данных сохранена в $BACKUP_PATH" +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 + fi + + # Получить текущую ветку + CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + print_warning "Текущая ветка: $CURRENT_BRANCH" + + # Обновить код + sudo -u "$REAL_USER" git fetch --all + sudo -u "$REAL_USER" git pull origin "$CURRENT_BRANCH" + + # Восстановить .env + if [ -f "/tmp/ai-review-env-backup" ]; then + cp /tmp/ai-review-env-backup backend/.env + rm /tmp/ai-review-env-backup + fi + + print_success "Код обновлен" +else + print_warning "Не git репозиторий, пропускаем обновление кода" + echo "Если вы хотите обновить код вручную, сделайте это сейчас" + read -p "Продолжить? (y/n): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + print_error "Отменено" + systemctl start "$SERVICE_NAME" + exit 1 + fi +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" + +# Запустить сервис +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 + +# ============================================================================ +# Финал +# ============================================================================ +echo "" +echo -e "${GREEN}╔════════════════════════════════════════╗${NC}" +echo -e "${GREEN}║ Redeploy завершен успешно! ✅ ║${NC}" +echo -e "${GREEN}╚════════════════════════════════════════╝${NC}" +echo "" +echo "Сервис: http://$(hostname -I | awk '{print $1}'):8000" +echo "Статус: systemctl status $SERVICE_NAME" +echo "Логи: journalctl -u $SERVICE_NAME -f" +echo "" +echo "Backup создан: $BACKUP_PATH" +echo "" +echo -e "${YELLOW}Для отката к предыдущей версии:${NC}" +echo " 1. Остановите сервис: sudo systemctl stop $SERVICE_NAME" +echo " 2. Восстановите БД: sudo cp $BACKUP_PATH/review.db $INSTALL_DIR/backend/" +echo " 3. Откатите git: cd $INSTALL_DIR && sudo -u $REAL_USER git reset --hard HEAD~1" +echo " 4. Запустите redeploy снова: sudo ./redeploy-ubuntu.sh" +echo "" +