#!/bin/bash # ============================================================================= # SmartSolTech - Скрипт автоматического обновления # ============================================================================= set -e # Выход при любой ошибке # Цвета для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Функция для логирования log() { echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" } success() { echo -e "${GREEN}✅ $1${NC}" } warning() { echo -e "${YELLOW}⚠️ $1${NC}" } error() { echo -e "${RED}❌ $1${NC}" } # Функция проверки зависимостей check_dependencies() { log "Проверка зависимостей..." if ! command -v git &> /dev/null; then error "Git не установлен" exit 1 fi if ! command -v docker &> /dev/null; then error "Docker не установлен" exit 1 fi if ! command -v docker-compose &> /dev/null; then error "Docker Compose не установлен" exit 1 fi success "Все зависимости найдены" } # Функция очистки staticfiles cleanup_staticfiles() { log "Очистка staticfiles..." if [ -d "smartsoltech/staticfiles" ]; then warning "Найдена папка staticfiles, удаляем..." chmod -R 755 smartsoltech/staticfiles 2>/dev/null || true rm -rf smartsoltech/staticfiles success "Staticfiles очищены" fi } # Функция обновления кода update_code() { log "Обновление кода из репозитория..." # Сохраняем изменения если есть if ! git diff --quiet; then warning "Обнаружены локальные изменения, сохраняем..." git stash push -m "Auto stash before update $(date)" fi # Получаем обновления git fetch origin # Обновляем текущую ветку local current_branch=$(git rev-parse --abbrev-ref HEAD) git pull origin $current_branch success "Код обновлен с ветки $current_branch" } # Функция остановки контейнеров stop_containers() { log "Остановка контейнеров..." if docker-compose ps | grep -q "Up"; then docker-compose down success "Контейнеры остановлены" else warning "Контейнеры уже остановлены" fi } # Функция сборки образов build_images() { log "Сборка Docker образов..." # Принудительная пересборка docker-compose build --no-cache success "Образы собраны" } # Функция запуска контейнеров start_containers() { log "Запуск контейнеров..." # Запуск в фоновом режиме docker-compose up -d # Ожидание готовности log "Ожидание готовности сервисов..." sleep 10 # Проверка статуса if docker-compose ps | grep -q "Exit"; then error "Некоторые контейнеры завершились с ошибкой" docker-compose ps return 1 fi success "Контейнеры запущены" } # Функция выполнения миграций run_migrations() { log "Выполнение миграций Django..." # Ожидание готовности БД log "Ожидание готовности базы данных..." sleep 15 # Выполнение миграций docker-compose exec -T web python smartsoltech/manage.py migrate success "Миграции выполнены" } # Функция сбора статических файлов collect_static() { log "Сбор статических файлов..." docker-compose exec -T web python smartsoltech/manage.py collectstatic --noinput success "Статические файлы собраны" } # Функция проверки состояния сервисов health_check() { log "Проверка состояния сервисов..." # Проверка веб-сервера local max_attempts=30 local attempt=1 while [ $attempt -le $max_attempts ]; do if curl -sf http://localhost:8000/ > /dev/null 2>&1; then success "Веб-сервер доступен" break fi if [ $attempt -eq $max_attempts ]; then error "Веб-сервер недоступен после $max_attempts попыток" return 1 fi log "Попытка $attempt/$max_attempts - ожидание веб-сервера..." sleep 5 ((attempt++)) done # Показать статус контейнеров echo "" log "Статус контейнеров:" docker-compose ps success "Проверка здоровья завершена" } # Функция отображения логов show_logs() { log "Последние логи сервисов:" echo "" docker-compose logs --tail=20 web } # Функция бэкапа в удаленный репозиторий backup_to_remote() { log "Создание бэкапа в удаленном репозитории..." if git remote | grep -q "backup"; then # Проверяем есть ли изменения для коммита if ! git diff --quiet || ! git diff --cached --quiet; then git add . git commit -m "Auto backup before update $(date '+%Y-%m-%d %H:%M:%S')" fi # Пушим в backup git push backup master success "Бэкап создан в удаленном репозитории" else warning "Backup репозиторий не настроен, пропускаем" fi } # Главная функция main() { echo "" echo "🚀 SmartSolTech - Автоматическое обновление" echo "==========================================" echo "" # Проверка что мы в правильной директории if [ ! -f "docker-compose.yml" ]; then error "docker-compose.yml не найден. Запустите скрипт из корня проекта." exit 1 fi local start_time=$(date +%s) # Выполняем все этапы check_dependencies backup_to_remote cleanup_staticfiles update_code stop_containers build_images start_containers run_migrations collect_static health_check local end_time=$(date +%s) local duration=$((end_time - start_time)) echo "" echo "🎉 Обновление завершено успешно!" echo "⏱️ Время выполнения: ${duration} секунд" echo "" echo "📊 Полезная информация:" echo " • Веб-сайт: http://localhost:8000" echo " • Админка: http://localhost:8000/admin" echo " • PgAdmin: http://localhost:8080" echo "" # Предложение показать логи read -p "Показать логи сервисов? (y/N): " show_logs_choice if [[ $show_logs_choice =~ ^[Yy]$ ]]; then show_logs fi success "Готово!" } # Обработка прерываний trap 'echo ""; error "Обновление прервано пользователем"; exit 130' INT TERM # Обработка ошибок error_handler() { local line_no=$1 error "Ошибка на строке $line_no" echo "" echo "Для диагностики можете выполнить:" echo " docker-compose logs" echo " docker-compose ps" exit 1 } trap 'error_handler $LINENO' ERR # Запуск с параметрами case "${1:-}" in --help|-h) echo "SmartSolTech - Скрипт автоматического обновления" echo "" echo "Использование:" echo " $0 - Полное обновление (по умолчанию)" echo " $0 --help - Показать эту справку" echo " $0 --logs - Показать логи без обновления" echo " $0 --status - Показать статус без обновления" echo "" exit 0 ;; --logs) show_logs exit 0 ;; --status) docker-compose ps health_check exit 0 ;; "") main ;; *) error "Неизвестный параметр: $1" echo "Используйте --help для справки" exit 1 ;; esac