/
hanymi
/
model-bridge
Обзор
Документация
Войти
/
hanymi
/
model-bridge
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
deploy_script.sh
153 строки
6 KB
user
refact setup
22 фев 2026, 14:47
22 фев 2026, 14:47
3dee663
Код
Авторство
О чём код?
#!/bin/bash # ============================================== # Model Bridge — Скрипт обновления (деплой) # # Проверяет обновления в git и при необходимости # пересобирает только изменённые контейнеры. # # Безопасен для запуска по cron: # - Не использует интерактивный ввод # - Корректная обработка ошибок # - Логирование с временными метками # - Не привязан к текущей рабочей директории # - Блокировка от одновременного запуска (flock) # # Установка в cron (каждые 5 минут): # */5 * * * * /path/to/model-bridge/deploy_script.sh >> /var/log/model-bridge-deploy.log 2>&1 # ============================================== set -euo pipefail # --- Конфигурация --- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$SCRIPT_DIR" GIT_BRANCH="main" LOCK_FILE="/tmp/model-bridge-deploy.lock" LOG_PREFIX="[model-bridge-deploy]" # --- Функции логирования --- log_info() { echo "${LOG_PREFIX} $(date '+%Y-%m-%d %H:%M:%S') [ИНФО] $1"; } log_ok() { echo "${LOG_PREFIX} $(date '+%Y-%m-%d %H:%M:%S') [✓] $1"; } log_warn() { echo "${LOG_PREFIX} $(date '+%Y-%m-%d %H:%M:%S') [!] $1"; } log_error() { echo "${LOG_PREFIX} $(date '+%Y-%m-%d %H:%M:%S') [✗] $1"; } # --- Блокировка от одновременного запуска --- exec 9>"$LOCK_FILE" if ! flock -n 9; then log_warn "Другой экземпляр деплоя уже запущен, выходим." exit 0 fi # --- Очистка при выходе --- cleanup() { flock -u 9 2>/dev/null || true rm -f "$LOCK_FILE" 2>/dev/null || true } trap cleanup EXIT # --- Обработка ошибок --- on_error() { log_error "Произошла ошибка на строке $1. Деплой прерван." exit 1 } trap 'on_error $LINENO' ERR # ============================================== # 1. Проверка обновлений в Git # ============================================== log_info "Проверка обновлений..." cd "$PROJECT_DIR" # Проверяем что это git-репозиторий if [ ! -d ".git" ]; then log_error "Не найден git-репозиторий в $PROJECT_DIR" exit 1 fi PREV_COMMIT=$(git rev-parse HEAD 2>/dev/null) git fetch origin 2>/dev/null REMOTE_COMMIT=$(git rev-parse "origin/${GIT_BRANCH}" 2>/dev/null) if [ "$PREV_COMMIT" == "$REMOTE_COMMIT" ]; then log_info "Нет новых изменений." exit 0 fi log_info "Обнаружены изменения: ${PREV_COMMIT:0:8} → ${REMOTE_COMMIT:0:8}" # ============================================== # 2. Получение изменений # ============================================== log_info "Применяем изменения..." git reset --hard "origin/${GIT_BRANCH}" # ============================================== # 3. Восстановление прав для qwen директорий # ============================================== # ВАЖНО: git reset может сбросить права. Восстанавливаем. if [ -d "${PROJECT_DIR}/qwen/home" ]; then chown -R 1000:1000 "${PROJECT_DIR}/qwen/home" 2>/dev/null || true chown -R 1000:1000 "${PROJECT_DIR}/qwen/data" 2>/dev/null || true chown -R 1000:1000 "${PROJECT_DIR}/qwen/logs" 2>/dev/null || true log_info "Права на qwen-директории восстановлены (UID 1000)" fi # ============================================== # 4. Определение изменённых сервисов # ============================================== CHANGED_FILES=$(git diff --name-only "$PREV_COMMIT" "$REMOTE_COMMIT" 2>/dev/null || echo "") REBUILD_SERVICES="" if echo "$CHANGED_FILES" | grep -q "^gateway/"; then REBUILD_SERVICES="$REBUILD_SERVICES gateway worker" log_info "Изменения в gateway → пересборка gateway + worker" fi if echo "$CHANGED_FILES" | grep -q "^nginx/"; then REBUILD_SERVICES="$REBUILD_SERVICES nginx" log_info "Изменения в nginx → пересборка nginx" fi if echo "$CHANGED_FILES" | grep -q "^qwen/"; then REBUILD_SERVICES="$REBUILD_SERVICES qwen" log_info "Изменения в qwen → пересборка qwen" fi if echo "$CHANGED_FILES" | grep -q "^docker-compose.yml\|^\.env\|^install.sh"; then REBUILD_SERVICES="ALL" log_info "Изменения в конфигурации → полная пересборка" fi # ============================================== # 5. Пересборка # ============================================== if [ "$REBUILD_SERVICES" == "ALL" ] || [ -z "$REBUILD_SERVICES" ] || [ ! -f "docker-compose.yml" ]; then log_info "Генерация конфигураций и полная пересборка сервисов..." sudo ./install.sh --resume else log_info "Выборочная пересборка: ${REBUILD_SERVICES}" for service in $REBUILD_SERVICES; do docker compose build "$service" 2>&1 | tail -3 docker compose up -d --no-deps "$service" done fi # ============================================== # 6. Проверка здоровья # ============================================== sleep 10 log_info "Статус контейнеров:" docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || docker compose ps RUNNING=$(docker compose ps --format "{{.State}}" 2>/dev/null | grep -c "running" || echo "?") TOTAL=$(docker compose ps --format "{{.State}}" 2>/dev/null | wc -l || echo "?") log_info "Запущено контейнеров: ${RUNNING}/${TOTAL}" # ============================================== # 7. Очистка # ============================================== docker system prune -f > /dev/null 2>&1 || true log_ok "Деплой завершён! Коммит: ${REMOTE_COMMIT:0:8}"