#!/bin/bash # Скрипт развертывания AI Code Review Platform на Ubuntu с systemd set -e # Цвета для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Проверка что скрипт запущен с sudo if [ "$EUID" -ne 0 ]; then echo -e "${RED}Ошибка: Этот скрипт должен быть запущен с sudo${NC}" echo "Используйте: sudo ./deploy-ubuntu.sh" exit 1 fi # Получаем имя реального пользователя (не root) REAL_USER=${SUDO_USER:-$USER} REAL_HOME=$(eval echo ~$REAL_USER) echo -e "${BLUE}" echo "=========================================" echo " AI Code Review Platform - Установка" echo "=========================================" echo -e "${NC}" # 1. Проверка зависимостей echo -e "${YELLOW}[1/10] Проверка системных зависимостей...${NC}" # Проверка Python if ! command -v python3 &> /dev/null; then echo -e "${RED}Python 3 не установлен!${NC}" echo "Установка Python 3..." apt-get update apt-get install -y python3 python3-pip python3-venv fi # Проверка Node.js if ! command -v node &> /dev/null; then echo -e "${RED}Node.js не установлен!${NC}" echo "Установка Node.js..." curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs fi # Установка nginx (опционально) if ! command -v nginx &> /dev/null; then echo -e "${YELLOW}Установить nginx как reverse proxy? [y/N]${NC}" read -r install_nginx if [[ "$install_nginx" =~ ^[Yy]$ ]]; then apt-get install -y nginx fi fi echo -e "${GREEN}✓ Зависимости проверены${NC}" # 2. Определение пути установки echo -e "${YELLOW}[2/10] Настройка путей...${NC}" # Определить, откуда запущен скрипт SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CURRENT_DIR="$SCRIPT_DIR" # Спросить пользователя, куда устанавливать echo "Текущая директория: $CURRENT_DIR" echo "" echo "Выберите директорию установки:" echo " 1) Использовать текущую директорию ($CURRENT_DIR)" echo " 2) Установить в /opt/ai-review" echo "" read -p "Выбор [1/2] (по умолчанию 1): " install_choice install_choice=${install_choice:-1} if [ "$install_choice" = "2" ]; then INSTALL_DIR="/opt/ai-review" NEED_COPY=true else INSTALL_DIR="$CURRENT_DIR" NEED_COPY=false fi echo "Директория установки: $INSTALL_DIR" # 3. Копирование файлов (если нужно) echo -e "${YELLOW}[3/10] Подготовка файлов проекта...${NC}" if [ "$NEED_COPY" = true ]; then echo "Копирование в $INSTALL_DIR..." mkdir -p "$INSTALL_DIR" cp -r "$CURRENT_DIR"/* "$INSTALL_DIR"/ || { echo -e "${RED}✗ Ошибка копирования файлов${NC}" exit 1 } chown -R "$REAL_USER":"$REAL_USER" "$INSTALL_DIR" echo -e "${GREEN}✓ Файлы скопированы${NC}" else echo "Используем текущую директорию" chown -R "$REAL_USER":"$REAL_USER" "$INSTALL_DIR" echo -e "${GREEN}✓ Права установлены${NC}" fi cd "$INSTALL_DIR" # 4. Сборка frontend echo -e "${YELLOW}[4/10] Сборка frontend...${NC}" cd frontend # Проверить наличие package.json if [ ! -f "package.json" ]; then echo -e "${RED}✗ Не найден package.json${NC}" exit 1 fi # Создаем .env.production для относительных путей cat > .env.production << 'EOF' # Production - используем относительные пути VITE_API_URL=/api VITE_WS_URL= EOF echo "Установка npm зависимостей..." sudo -u "$REAL_USER" npm install || { echo -e "${RED}✗ Ошибка установки npm зависимостей${NC}" exit 1 } echo "Сборка frontend..." sudo -u "$REAL_USER" npm run build || { echo -e "${RED}✗ Ошибка сборки frontend${NC}" exit 1 } # Проверить, что build создан if [ ! -d "../backend/public" ]; then echo -e "${RED}✗ Frontend не собрался (отсутствует backend/public)${NC}" exit 1 fi cd .. echo -e "${GREEN}✓ Frontend собран (файлов: $(ls -1 backend/public | wc -l))${NC}" # 5. Установка Python зависимостей echo -e "${YELLOW}[5/10] Установка Python зависимостей...${NC}" cd backend # Проверить наличие requirements.txt if [ ! -f "requirements.txt" ]; then echo -e "${RED}✗ Не найден requirements.txt${NC}" exit 1 fi echo "Создание Python virtual environment..." sudo -u "$REAL_USER" python3 -m venv venv || { echo -e "${RED}✗ Ошибка создания venv${NC}" exit 1 } # Проверить, что venv создан if [ ! -d "venv" ]; then echo -e "${RED}✗ venv не создан${NC}" exit 1 fi echo "Установка Python пакетов..." sudo -u "$REAL_USER" bash -c "source venv/bin/activate && pip install --upgrade pip && pip install -r requirements.txt" || { echo -e "${RED}✗ Ошибка установки Python зависимостей${NC}" exit 1 } echo -e "${GREEN}✓ Python зависимости установлены${NC}" # Применить миграции БД echo "Применение миграций БД..." if [ -f "migrate.py" ]; then sudo -u "$REAL_USER" bash -c "source venv/bin/activate && python migrate.py" || { echo -e "${YELLOW}⚠️ Предупреждение: миграции не применились${NC}" } # Проверить, что БД создана if [ -f "review.db" ]; then echo -e "${GREEN}✓ База данных создана${NC}" else echo -e "${YELLOW}⚠️ База данных будет создана при первом запуске${NC}" fi else echo -e "${YELLOW}⚠️ Скрипт миграции не найден, БД будет создана автоматически${NC}" fi cd .. echo -e "${GREEN}✓ Backend настроен${NC}" # 6. Настройка .env echo -e "${YELLOW}[6/10] Настройка конфигурации...${NC}" if [ ! -f "backend/.env" ]; then echo "Создание .env файла..." # Генерируем ключ шифрования ENCRYPTION_KEY=$(python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())") cat > backend/.env << EOF # Ollama Configuration OLLAMA_BASE_URL=http://localhost:11434 OLLAMA_MODEL=mistral:7b # Database DATABASE_URL=sqlite+aiosqlite:///$INSTALL_DIR/backend/review.db # Security SECRET_KEY=$(openssl rand -hex 32) ENCRYPTION_KEY=$ENCRYPTION_KEY # Master Git Tokens (optional) MASTER_GITEA_TOKEN= MASTER_GITHUB_TOKEN= MASTER_BITBUCKET_TOKEN= # Server HOST=0.0.0.0 PORT=8000 DEBUG=false # CORS CORS_ORIGINS=http://localhost:8000,http://localhost:5173 EOF chown "$REAL_USER":"$REAL_USER" backend/.env echo -e "${GREEN}✓ Создан .env файл${NC}" echo -e "${YELLOW}⚠️ ВАЖНО: Отредактируйте backend/.env и добавьте необходимые токены!${NC}" else echo ".env уже существует" fi # 7. Создание systemd service echo -e "${YELLOW}[7/10] Создание systemd service...${NC}" cat > /etc/systemd/system/ai-review.service << EOF [Unit] Description=AI Code Review Platform After=network.target [Service] Type=simple User=$REAL_USER Group=$REAL_USER WorkingDirectory=$INSTALL_DIR/backend Environment="PATH=$INSTALL_DIR/backend/venv/bin:/usr/local/bin:/usr/bin:/bin" ExecStart=$INSTALL_DIR/backend/venv/bin/python3 -m uvicorn app.main:app --host 0.0.0.0 --port 8000 Restart=always RestartSec=10 StandardOutput=append:/var/log/ai-review/access.log StandardError=append:/var/log/ai-review/error.log # Security NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=$INSTALL_DIR/backend [Install] WantedBy=multi-user.target EOF echo -e "${GREEN}✓ Systemd service создан${NC}" # 8. Создание директории для логов echo -e "${YELLOW}[8/10] Настройка логирования...${NC}" mkdir -p /var/log/ai-review chown "$REAL_USER":"$REAL_USER" /var/log/ai-review echo -e "${GREEN}✓ Директория логов создана${NC}" # 9. Включение и запуск сервиса echo -e "${YELLOW}[9/10] Запуск сервиса...${NC}" systemctl daemon-reload systemctl enable ai-review.service systemctl start ai-review.service # Ждем запуска echo "Ожидание запуска (5 секунд)..." sleep 5 # Проверка статуса if systemctl is-active --quiet ai-review.service; then echo -e "${GREEN}✓ Сервис успешно запущен${NC}" else echo -e "${RED}✗ Ошибка запуска сервиса${NC}" echo "" echo -e "${YELLOW}Последние 30 строк логов:${NC}" journalctl -u ai-review.service -n 30 --no-pager echo "" echo -e "${YELLOW}Для детальной диагностики запустите:${NC}" echo " journalctl -u ai-review.service -n 100" echo " cd $INSTALL_DIR/backend && source venv/bin/activate && python -m uvicorn app.main:app" echo "" echo -e "${YELLOW}Проверьте что:${NC}" echo " 1. venv создан: ls -la $INSTALL_DIR/backend/venv" echo " 2. Frontend собран: ls -la $INSTALL_DIR/backend/public" echo " 3. .env настроен: cat $INSTALL_DIR/backend/.env" exit 1 fi # 10. Настройка nginx (опционально) echo -e "${YELLOW}[10/10] Настройка nginx...${NC}" if command -v nginx &> /dev/null; then echo -e "${YELLOW}Настроить nginx как reverse proxy? [y/N]${NC}" read -r setup_nginx if [[ "$setup_nginx" =~ ^[Yy]$ ]]; then echo "Введите доменное имя (или нажмите Enter для localhost):" read -r domain_name domain_name=${domain_name:-localhost} cat > /etc/nginx/sites-available/ai-review << EOF server { listen 80; server_name $domain_name; client_max_body_size 50M; location / { proxy_pass http://localhost:8000; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } location /ws { proxy_pass http://localhost:8000; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; } location /api { proxy_pass http://localhost:8000; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; } } EOF ln -sf /etc/nginx/sites-available/ai-review /etc/nginx/sites-enabled/ nginx -t && systemctl reload nginx echo -e "${GREEN}✓ Nginx настроен${NC}" echo -e "${GREEN}✓ Доступ: http://$domain_name${NC}" fi fi # Итоговая информация echo "" echo -e "${GREEN}=========================================${NC}" echo -e "${GREEN} 🎉 Установка завершена!${NC}" echo -e "${GREEN}=========================================${NC}" echo "" echo -e "📍 ${BLUE}Директория установки:${NC} $INSTALL_DIR" echo -e "📍 ${BLUE}Конфигурация:${NC} $INSTALL_DIR/backend/.env" echo -e "📍 ${BLUE}Логи:${NC} /var/log/ai-review/" echo "" echo -e "${YELLOW}Полезные команды:${NC}" echo "" echo -e " ${BLUE}Статус сервиса:${NC}" echo " sudo systemctl status ai-review" echo "" echo -e " ${BLUE}Перезапуск:${NC}" echo " sudo systemctl restart ai-review" echo "" echo -e " ${BLUE}Остановка:${NC}" echo " sudo systemctl stop ai-review" echo "" echo -e " ${BLUE}Просмотр логов:${NC}" echo " sudo journalctl -u ai-review -f" echo " tail -f /var/log/ai-review/access.log" echo " tail -f /var/log/ai-review/error.log" echo "" echo -e " ${BLUE}Редактирование конфигурации:${NC}" echo " sudo nano $INSTALL_DIR/backend/.env" echo " sudo systemctl restart ai-review" echo "" echo -e "${GREEN}🌐 Приложение доступно по адресу:${NC}" echo -e " ${BLUE}http://localhost:8000${NC}" if [ -n "$domain_name" ] && [ "$domain_name" != "localhost" ]; then echo -e " ${BLUE}http://$domain_name${NC}" fi echo "" echo -e "${YELLOW}⚠️ Не забудьте:${NC}" echo " 1. Отредактировать $INSTALL_DIR/backend/.env" echo " 2. Добавить токены для Git платформ" echo " 3. Настроить firewall (разрешить порт 80/443)" echo "" echo -e "${YELLOW}📦 Проверка установки:${NC}" echo " Backend venv: $([ -d $INSTALL_DIR/backend/venv ] && echo '✓' || echo '✗')" echo " Backend DB: $([ -f $INSTALL_DIR/backend/review.db ] && echo '✓' || echo '⚠️ будет создана')" echo " Frontend build: $([ -d $INSTALL_DIR/backend/public ] && echo '✓' || echo '✗')" echo "" echo -e "${GREEN}✨ Готово к работе!${NC}" echo ""