Add project and deployment instruction (docs/DEPLOYMENT.md)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ars
2026-02-19 18:12:09 +00:00
commit 53c572ef46
94 changed files with 9200 additions and 0 deletions

248
scripts/rebrand.sh Executable file
View File

@@ -0,0 +1,248 @@
#!/bin/bash
# Скрипт ребрендинга Open WebUI для iiEasy
# ВНИМАНИЕ: Этот скрипт может ломать OAuth!
# Рекомендуется использовать rebrand_complete.sh для полного ребрендинга
# Заменяет логотипы, favicon, удаляет упоминания Open WebUI, отключает проверку обновлений
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
MEDIA_DIR="$PROJECT_DIR/media"
CONTAINER_NAME="open-webui"
echo "=== Ребрендинг Open WebUI для iiEasy ==="
# Проверка наличия контейнера
if ! docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Ошибка: Контейнер ${CONTAINER_NAME} не найден. Запустите docker-compose up -d сначала."
exit 1
fi
# Проверка, что контейнер запущен
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Ошибка: Контейнер ${CONTAINER_NAME} не запущен. Запустите docker-compose up -d."
exit 1
fi
echo "1. Замена логотипов и favicon..."
# Важно: Open WebUI может использовать скомпилированные статические файлы
# Нужно найти правильные пути и заменить файлы там, где они реально используются
# Определяем пути для статических файлов в Open WebUI
# Open WebUI использует /app/web/build/_app/immutable/ для статических файлов
STATIC_DIRS=(
"/app/web/build/_app/immutable"
"/app/web/static"
"/app/web/build"
"/app/backend/static"
"/app/static"
"/app/public"
)
# Находим существующую директорию со статическими файлами
STATIC_DIR=""
for dir in "${STATIC_DIRS[@]}"; do
if docker exec "${CONTAINER_NAME}" test -d "$dir" 2>/dev/null; then
STATIC_DIR="$dir"
echo " Найдена директория статических файлов: $STATIC_DIR"
break
fi
done
if [ -z "$STATIC_DIR" ]; then
echo " Предупреждение: Директория статических файлов не найдена, пробуем найти через поиск favicon..."
# Ищем где находятся существующие favicon файлы
FAVICON_PATH=$(docker exec "${CONTAINER_NAME}" find /app -name "favicon.png" -o -name "favicon.ico" 2>/dev/null | head -1)
if [ -n "$FAVICON_PATH" ]; then
STATIC_DIR=$(dirname "$FAVICON_PATH")
echo " Найдена директория через поиск favicon: $STATIC_DIR"
else
STATIC_DIR="/app/web/build/_app/immutable"
echo " Используем стандартный путь: $STATIC_DIR"
# Создаем директорию если её нет
docker exec "${CONTAINER_NAME}" mkdir -p "$STATIC_DIR" 2>/dev/null || true
fi
fi
# Копирование логотипов (приоритет: PNG > SVG)
# Копируем во все найденные директории
for target_dir in "$STATIC_DIR" "/app/web/build/_app/immutable" "/app/web/static" "/app/web/build"; do
if docker exec "${CONTAINER_NAME}" test -d "$target_dir" 2>/dev/null || [ "$target_dir" = "$STATIC_DIR" ]; then
echo " Копирование в $target_dir..."
# Логотипы
if [ -f "$MEDIA_DIR/logo.png" ]; then
docker cp "$MEDIA_DIR/logo.png" "${CONTAINER_NAME}:${target_dir}/logo.png" 2>/dev/null || true
docker cp "$MEDIA_DIR/logo.png" "${CONTAINER_NAME}:${target_dir}/logo.svg" 2>/dev/null || true
elif [ -f "$MEDIA_DIR/logo-light.svg" ]; then
docker cp "$MEDIA_DIR/logo-light.svg" "${CONTAINER_NAME}:${target_dir}/logo.svg" 2>/dev/null || true
fi
if [ -f "$MEDIA_DIR/logo-dark.svg" ]; then
docker cp "$MEDIA_DIR/logo-dark.svg" "${CONTAINER_NAME}:${target_dir}/logo-dark.svg" 2>/dev/null || true
fi
# Favicon
if [ -f "$MEDIA_DIR/favicon.ico" ]; then
docker cp "$MEDIA_DIR/favicon.ico" "${CONTAINER_NAME}:${target_dir}/favicon.ico" 2>/dev/null || true
elif [ -f "$MEDIA_DIR/favicon.png" ]; then
docker cp "$MEDIA_DIR/favicon.png" "${CONTAINER_NAME}:${target_dir}/favicon.png" 2>/dev/null || true
docker cp "$MEDIA_DIR/favicon.png" "${CONTAINER_NAME}:${target_dir}/favicon.ico" 2>/dev/null || true
docker cp "$MEDIA_DIR/favicon.png" "${CONTAINER_NAME}:${target_dir}/favicon-96x96.png" 2>/dev/null || true
elif [ -f "$MEDIA_DIR/favicon.svg" ]; then
docker cp "$MEDIA_DIR/favicon.svg" "${CONTAINER_NAME}:${target_dir}/favicon.svg" 2>/dev/null || true
fi
fi
done
# Поиск и замена существующих favicon и logo файлов везде в /app
echo " Поиск существующих favicon и logo файлов для замены..."
EXISTING_FAVICONS=$(docker exec "${CONTAINER_NAME}" find /app -type f \( -name "favicon.png" -o -name "favicon.ico" -o -name "favicon.svg" \) 2>/dev/null | head -10)
EXISTING_LOGOS=$(docker exec "${CONTAINER_NAME}" find /app -type f \( -name "logo.png" -o -name "logo.svg" \) 2>/dev/null | head -10)
echo " Найдено favicon файлов: $(echo "$EXISTING_FAVICONS" | wc -l)"
echo " Найдено logo файлов: $(echo "$EXISTING_LOGOS" | wc -l)"
# Заменяем существующие favicon файлы
if [ -f "$MEDIA_DIR/favicon.png" ]; then
echo "$EXISTING_FAVICONS" | while read -r favicon_file; do
if [ -n "$favicon_file" ]; then
echo " Замена: $favicon_file"
docker cp "$MEDIA_DIR/favicon.png" "${CONTAINER_NAME}:${favicon_file}" 2>/dev/null || true
# Также создаем .ico версию рядом
favicon_dir=$(dirname "$favicon_file")
docker cp "$MEDIA_DIR/favicon.png" "${CONTAINER_NAME}:${favicon_dir}/favicon.ico" 2>/dev/null || true
fi
done
fi
# Заменяем существующие logo файлы
if [ -f "$MEDIA_DIR/logo.png" ]; then
echo "$EXISTING_LOGOS" | while read -r logo_file; do
if [ -n "$logo_file" ]; then
echo " Замена: $logo_file"
docker cp "$MEDIA_DIR/logo.png" "${CONTAINER_NAME}:${logo_file}" 2>/dev/null || true
fi
done
fi
# Также копируем в корень public для веб-доступа
PUBLIC_DIRS=(
"/app/web/public"
"/app/public"
"/app/backend/public"
)
for pub_dir in "${PUBLIC_DIRS[@]}"; do
if docker exec "${CONTAINER_NAME}" test -d "$pub_dir" 2>/dev/null; then
echo " Копирование в $pub_dir..."
if [ -f "$MEDIA_DIR/logo.png" ]; then
docker cp "$MEDIA_DIR/logo.png" "${CONTAINER_NAME}:${pub_dir}/logo.png" 2>/dev/null || true
fi
if [ -f "$MEDIA_DIR/favicon.png" ]; then
docker cp "$MEDIA_DIR/favicon.png" "${CONTAINER_NAME}:${pub_dir}/favicon.png" 2>/dev/null || true
docker cp "$MEDIA_DIR/favicon.png" "${CONTAINER_NAME}:${pub_dir}/favicon.ico" 2>/dev/null || true
fi
break
fi
done
echo " Примечание: Если логотипы не изменились, настройте их через Admin Panel:"
echo " Settings → Appearance → Logo (загрузите файлы из /app/media/)"
echo "2. Поиск и замена текстовых упоминаний 'Open WebUI'..."
# Поиск файлов с упоминаниями Open WebUI в статических файлах и конфигурации
# ВАЖНО: ИСКЛЮЧАЕМ ВСЕ файлы, связанные с OAuth/Authentik/аутентификацией
# Это включает: oauth.py, auth.py, login.py, и все файлы в директориях oauth, oidc, auth, login
docker exec "${CONTAINER_NAME}" find /app -type f \( -name "*.py" -o -name "*.html" -o -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" -o -name "*.json" -o -name "*.svelte" \) \
! -path "*/oauth*" ! -path "*/oidc*" ! -path "*authentik*" ! -path "*openid*" \
! -name "*oauth*" ! -name "*oidc*" ! -name "*auth*" ! -name "*login*" \
! -path "*/utils/oauth*" ! -path "*/utils/auth*" ! -path "*/backend/open_webui/utils/oauth*" \
-exec grep -l "Open WebUI\|open-webui\|openwebui\|\(Open WebUI\)" {} \; 2>/dev/null | while read file; do
echo " Обработка: $file"
# Замена "Open WebUI" на "iiEasyWeb" (только в тексте интерфейса, не в URL)
docker exec "${CONTAINER_NAME}" sed -i 's/Open WebUI/iiEasyWeb/g' "$file" 2>/dev/null || true
# Удаление "(Open WebUI)" в скобках - заменяем на пустую строку или только "iiEasyWeb"
docker exec "${CONTAINER_NAME}" sed -i 's/(Open WebUI)//g' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i 's/\(Open WebUI\)//g' "$file" 2>/dev/null || true
# Замена "iiEasyWeb (Open WebUI)" на просто "iiEasyWeb"
docker exec "${CONTAINER_NAME}" sed -i 's/iiEasyWeb (Open WebUI)/iiEasyWeb/g' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i 's/iiEasyWeb \(Open WebUI\)/iiEasyWeb/g' "$file" 2>/dev/null || true
# ВАЖНО: НЕ заменяем open-webui в нижнем регистре, так как это может быть частью URL или конфигурации OAuth
done
# Специальная обработка для удаления "(Open WebUI)" из заголовков и описаний
echo "3. Удаление упоминаний '(Open WebUI)' из интерфейса..."
# ИСКЛЮЧАЕМ файлы OAuth/Authentik
docker exec "${CONTAINER_NAME}" find /app -type f \( -name "*.html" -o -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" -o -name "*.svelte" \) \
! -path "*/oauth*" ! -path "*/oidc*" ! -path "*authentik*" ! -path "*openid*" \
-exec grep -l "(Open WebUI)\|\(Open WebUI\)" {} \; 2>/dev/null | while read file; do
echo " Удаление '(Open WebUI)' из: $file"
# Удаляем различные варианты написания в скобках
docker exec "${CONTAINER_NAME}" sed -i 's/(Open WebUI)//g' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i 's/\(Open WebUI\)//g' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i 's/ (Open WebUI)//g' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i 's/ \(Open WebUI\)//g' "$file" 2>/dev/null || true
done
echo "4. Отключение проверки обновлений..."
# Поиск и отключение проверки обновлений через GitHub API
# ИСКЛЮЧАЕМ файлы OAuth/Authentik
docker exec "${CONTAINER_NAME}" find /app/backend -type f \( -name "*.py" -o -name "*.js" \) \
! -path "*/oauth*" ! -path "*/oidc*" ! -path "*authentik*" ! -path "*openid*" \
-exec grep -l "github.com.*releases\|check.*update\|update.*check" {} \; 2>/dev/null | while read file; do
echo " Отключение проверки обновлений в: $file"
# Комментирование вызовов GitHub API для проверки обновлений
docker exec "${CONTAINER_NAME}" sed -i 's|https://api.github.com/repos/open-webui|# https://api.github.com/repos/open-webui|g' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i 's|github.com/open-webui|# github.com/open-webui|g' "$file" 2>/dev/null || true
done
# Отключение проверки обновлений через переменные окружения (уже настроено в docker-compose.yml)
echo " Проверка обновлений отключена через переменные окружения"
echo "5. Удаление аналитики и телеметрии..."
# Поиск и отключение аналитики (более аккуратно, чтобы не сломать код)
# Комментируем только целые строки с импортами аналитики, а не части строк
# ИСКЛЮЧАЕМ файлы OAuth/Authentik
docker exec "${CONTAINER_NAME}" find /app/backend -type f \( -name "*.py" -o -name "*.js" \) \
! -path "*/oauth*" ! -path "*/oidc*" ! -path "*authentik*" ! -path "*openid*" \
-exec grep -l "from.*telemetry\|import.*telemetry\|analytics\|tracking\|gtag\|ga(\|google-analytics" {} \; 2>/dev/null | while read file; do
echo " Отключение аналитики в: $file"
# Комментируем только целые строки импорта, начинающиеся с from или import
docker exec "${CONTAINER_NAME}" sed -i '/^[[:space:]]*from.*telemetry/s/^/# /' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i '/^[[:space:]]*import.*telemetry/s/^/# /' "$file" 2>/dev/null || true
done
echo "6. Удаление 'Powered by' футеров..."
# Поиск футеров с упоминанием Open WebUI
# ИСКЛЮЧАЕМ файлы OAuth/Authentik
docker exec "${CONTAINER_NAME}" find /app/backend -type f \( -name "*.html" -o -name "*.js" -o -name "*.tsx" -o -name "*.jsx" \) \
! -path "*/oauth*" ! -path "*/oidc*" ! -path "*authentik*" ! -path "*openid*" \
-exec grep -l "Powered by\|powered by" {} \; 2>/dev/null | while read file; do
echo " Удаление футера в: $file"
docker exec "${CONTAINER_NAME}" sed -i '/Powered by.*[Oo]pen.*[Ww]eb[Uu][Ii]/d' "$file" 2>/dev/null || true
docker exec "${CONTAINER_NAME}" sed -i '/powered by.*[Oo]pen.*[Ww]eb[Uu][Ii]/d' "$file" 2>/dev/null || true
done
echo "7. Перезапуск контейнера для применения изменений..."
docker restart "${CONTAINER_NAME}" >/dev/null 2>&1 || {
echo "Предупреждение: Не удалось перезапустить контейнер автоматически."
echo "Перезапустите вручную: docker restart ${CONTAINER_NAME}"
}
echo ""
echo "=== Ребрендинг завершен! ==="
echo ""
echo "Проверьте изменения:"
echo " 1. Откройте https://odo.iieasy.ru в браузере"
echo " 2. Проверьте логотип и favicon"
echo " 3. Проверьте отсутствие упоминаний 'Open WebUI'"
echo ""
echo "Примечание: Если изменения не отображаются, очистите кеш браузера."