From 7f9c521fedb4b97087b425f47aa6ff0865645d63 Mon Sep 17 00:00:00 2001 From: joylessorchid Date: Tue, 24 Mar 2026 02:21:40 +0300 Subject: [PATCH] fix: remove "type" field from package.json + improve setup.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove "type": "commonjs" from package.json — fixes Turbopack ESM/CommonJS conflict causing white screen in dev mode - setup.sh: auto-generate passwords (PostgreSQL, MinIO, auth secret) - setup.sh: auto-install Docker/Node.js if missing (apt/nvm/brew) - setup.sh: backup existing .env before overwrite - setup.sh: create MinIO bucket via curl if mc not installed - setup.sh: add timeout errors for service readiness checks - setup.sh: include pgbouncer in local dev docker compose up Co-Authored-By: Claude Opus 4.6 --- package.json | 1 - setup.sh | 214 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 176 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index e94e775..c998f1f 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "keywords": [], "author": "", "license": "ISC", - "type": "commonjs", "dependencies": { "@livekit/components-react": "^2.9.20", "@livekit/components-styles": "^1.2.0", diff --git a/setup.sh b/setup.sh index e6595b6..c60ce58 100644 --- a/setup.sh +++ b/setup.sh @@ -64,6 +64,12 @@ generate_secret() { openssl rand -base64 32 2>/dev/null || head -c 32 /dev/urandom | base64 | tr -d '=/+' | head -c 32 } +generate_password() { + # 20 символов: буквы + цифры (безопасно для URL и CLI) + openssl rand -base64 24 2>/dev/null | tr -d '=/+' | head -c 20 || \ + head -c 24 /dev/urandom | base64 | tr -d '=/+' | head -c 20 +} + check_command() { if command -v "$1" &>/dev/null; then log_ok "$1 найден: $(command -v "$1")" @@ -74,21 +80,87 @@ check_command() { fi } +install_if_missing() { + local cmd="$1" install_hint="$2" + if command -v "$cmd" &>/dev/null; then + log_ok "$cmd найден: $(command -v "$cmd")" + return 0 + fi + + log_warn "$cmd не найден" + + # Попытка автоустановки через системные менеджеры + if [[ "$cmd" == "node" || "$cmd" == "npm" || "$cmd" == "npx" ]]; then + if command -v nvm &>/dev/null; then + echo -e " Установка Node.js через nvm..." + nvm install --lts 2>&1 | tail -3 + if command -v "$cmd" &>/dev/null; then + log_ok "$cmd установлен через nvm" + return 0 + fi + fi + fi + + # Автоустановка через apt/yum/brew если доступно + case "$cmd" in + docker) + if command -v apt-get &>/dev/null; then + if ask_yn "Установить Docker автоматически (apt)?" "y"; then + echo -e " Установка Docker..." + curl -fsSL https://get.docker.com | sh 2>&1 | tail -5 + sudo usermod -aG docker "$USER" 2>/dev/null || true + if command -v docker &>/dev/null; then + log_ok "Docker установлен" + return 0 + fi + fi + fi + ;; + node|npm|npx) + if command -v apt-get &>/dev/null; then + if ask_yn "Установить Node.js 22 автоматически (apt)?" "y"; then + echo -e " Установка Node.js..." + curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - 2>&1 | tail -3 + sudo apt-get install -y nodejs 2>&1 | tail -3 + if command -v "$cmd" &>/dev/null; then + log_ok "$cmd установлен" + return 0 + fi + fi + elif command -v brew &>/dev/null; then + if ask_yn "Установить Node.js через Homebrew?" "y"; then + brew install node 2>&1 | tail -3 + if command -v "$cmd" &>/dev/null; then + log_ok "$cmd установлен" + return 0 + fi + fi + fi + ;; + esac + + log_err "$cmd не удалось установить автоматически" + echo -e " ${YELLOW}Установи вручную:${NC} $install_hint" + return 1 +} + # ============================================================ # Main # ============================================================ print_banner -# --- Step 1: Check dependencies --- -log_step "Шаг 1/6 — Проверка зависимостей" +# --- Step 1: Check & install dependencies --- +log_step "Шаг 1/6 — Проверка и установка зависимостей" MISSING=0 -check_command docker || MISSING=1 -check_command "docker compose" 2>/dev/null || check_command docker-compose || MISSING=1 -check_command node || MISSING=1 -check_command npm || MISSING=1 -check_command npx || MISSING=1 +install_if_missing docker "https://docs.docker.com/get-docker/" || MISSING=1 +check_command "docker compose" 2>/dev/null || check_command docker-compose 2>/dev/null || { + log_err "docker compose не найден (нужен Docker Compose V2)" + MISSING=1 +} +install_if_missing node "https://nodejs.org/" || MISSING=1 +install_if_missing npm "https://nodejs.org/" || MISSING=1 if [[ "$MISSING" -eq 1 ]]; then log_err "Установи недостающие зависимости и запусти скрипт снова." @@ -137,39 +209,66 @@ fi # --- Step 3: Configure environment --- log_step "Шаг 3/6 — Настройка окружения" -echo "" -echo -e " ${BOLD}PostgreSQL${NC}" -ask "Пароль PostgreSQL" "postgres" PG_PASSWORD +# Автогенерация паролей +PG_PASSWORD=$(generate_password) +MINIO_USER="minio-$(head -c 4 /dev/urandom | xxd -p)" +MINIO_PASS=$(generate_password) +AUTH_SECRET=$(generate_secret) +DEV_ACCESS_KEY=$(generate_password | head -c 16) +S3_BUCKET="liveserver" echo "" -echo -e " ${BOLD}MinIO (S3 Storage)${NC}" -ask "MinIO root user" "minioadmin" MINIO_USER -ask_secret "MinIO root password" "minioadmin" MINIO_PASS -ask "Название S3 bucket" "liveserver" S3_BUCKET +echo -e " ${GREEN}${BOLD}Пароли сгенерированы автоматически:${NC}" +echo -e " ${CYAN}PostgreSQL:${NC} ${PG_PASSWORD}" +echo -e " ${CYAN}MinIO user:${NC} ${MINIO_USER}" +echo -e " ${CYAN}MinIO password:${NC} ${MINIO_PASS}" +echo -e " ${CYAN}Auth secret:${NC} ${AUTH_SECRET:0:16}..." +if [[ "$MODE" == "1" ]]; then + echo -e " ${CYAN}DEV_ACCESS_KEY:${NC} ${DEV_ACCESS_KEY}" +fi +echo "" +echo -e " ${YELLOW}Все пароли сохранены в .env — можешь изменить позже${NC}" + +if ask_yn "Хочешь задать свои пароли вместо сгенерированных?" "n"; then + echo "" + echo -e " ${BOLD}PostgreSQL${NC}" + ask "Пароль PostgreSQL" "$PG_PASSWORD" PG_PASSWORD + + echo "" + echo -e " ${BOLD}MinIO (S3 Storage)${NC}" + ask "MinIO root user" "$MINIO_USER" MINIO_USER + ask_secret "MinIO root password" "$MINIO_PASS" MINIO_PASS + ask "Название S3 bucket" "$S3_BUCKET" S3_BUCKET + + if [[ "$MODE" == "1" ]]; then + echo "" + echo -e " ${BOLD}Защита локалки${NC}" + ask "Ключ доступа (DEV_ACCESS_KEY)" "$DEV_ACCESS_KEY" DEV_ACCESS_KEY + fi +fi echo "" -echo -e " ${BOLD}LiveKit${NC}" +echo -e " ${BOLD}LiveKit${NC} (Enter чтобы пропустить, настроишь позже)" ask "LiveKit URL (wss://...)" "" LK_URL -ask "LiveKit API Key" "" LK_KEY -ask_secret "LiveKit API Secret" "" LK_SECRET -ask_secret "LiveKit Webhook Secret (Enter чтобы пропустить)" "" LK_WEBHOOK +LK_KEY="" +LK_SECRET="" +LK_WEBHOOK="" +if [[ -n "$LK_URL" ]]; then + ask "LiveKit API Key" "" LK_KEY + ask_secret "LiveKit API Secret" "" LK_SECRET + ask_secret "LiveKit Webhook Secret (Enter = пропустить)" "" LK_WEBHOOK +fi echo "" -echo -e " ${BOLD}AI Agent (Enter чтобы пропустить, настроишь позже)${NC}" +echo -e " ${BOLD}AI Agent${NC} (Enter чтобы пропустить, настроишь позже)" ask_secret "Deepgram API Key" "" DG_KEY ask_secret "OpenAI API Key" "" OAI_KEY -echo "" -echo -e " ${BOLD}Аутентификация${NC}" -AUTH_SECRET=$(generate_secret) -log_ok "Сгенерирован BETTER_AUTH_SECRET" - if [[ "$MODE" == "1" ]]; then - DEV_KEY=$(generate_secret | head -c 16) - echo "" - echo -e " ${BOLD}Защита локалки${NC}" - ask "Ключ доступа (DEV_ACCESS_KEY)" "$DEV_KEY" DEV_ACCESS_KEY - ask "Разрешённые IP (через запятую, Enter = все)" "" ALLOWED_IPS + ALLOWED_IPS="" + if ask_yn "Ограничить доступ по IP? (кроме localhost)" "n"; then + ask "Разрешённые IP (через запятую)" "" ALLOWED_IPS + fi fi # --- Step 4: Generate .env --- @@ -183,8 +282,15 @@ else S3_ENDPOINT="http://localhost:9000" fi +# Бэкап существующего .env +if [[ -f .env ]]; then + cp .env ".env.backup.$(date +%Y%m%d_%H%M%S)" + log_ok "Бэкап старого .env создан" +fi + cat > .env << ENVEOF # === Generated by setup.sh at $(date) === +# Все пароли сгенерированы автоматически — можешь заменить на свои. # Domain & SSL DOMAIN=${DOMAIN} @@ -195,8 +301,8 @@ DATABASE_URL=postgresql://postgres:${PG_PASSWORD}@localhost:5432/liveserver POSTGRES_PASSWORD=${PG_PASSWORD} # Redis -# For Docker containers: redis://redis:6379 -# For local npm run dev: redis://localhost:6379 +# Для Docker контейнеров: redis://redis:6379 +# Для локального npm run dev: redis://localhost:6379 REDIS_URL=redis://localhost:6379 # LiveKit @@ -232,13 +338,17 @@ log_ok ".env создан" # --- Step 5: Install & setup --- log_step "Шаг 5/6 — Установка и настройка" -# npm install +# npm install — автоматически если нет node_modules или package-lock изменился if [[ ! -d "node_modules" ]]; then echo -e " Установка npm зависимостей..." - npm install --silent 2>&1 | tail -3 - log_ok "npm install" + npm install 2>&1 | tail -5 + log_ok "npm install завершён" +elif [[ "package.json" -nt "node_modules/.package-lock.json" ]] 2>/dev/null; then + echo -e " package.json обновлён, переустановка зависимостей..." + npm install 2>&1 | tail -5 + log_ok "npm install завершён (обновление)" else - log_ok "node_modules уже существует" + log_ok "node_modules актуален" fi # Prisma generate @@ -251,7 +361,7 @@ echo -e " Запуск Docker контейнеров..." if [[ "$MODE" == "2" ]]; then docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build 2>&1 | tail -5 else - docker compose up -d postgres minio redis 2>&1 | tail -5 + docker compose up -d postgres minio redis pgbouncer 2>&1 | tail -5 fi log_ok "Docker контейнеры запущены" @@ -261,6 +371,10 @@ for i in $(seq 1 30); do if docker compose exec -T postgres pg_isready -U postgres &>/dev/null; then break fi + if [[ "$i" -eq 30 ]]; then + log_err "PostgreSQL не запустился за 30 секунд" + exit 1 + fi sleep 1 done log_ok "PostgreSQL готов" @@ -271,6 +385,10 @@ for i in $(seq 1 15); do if docker compose exec -T redis redis-cli ping 2>/dev/null | grep -q PONG; then break fi + if [[ "$i" -eq 15 ]]; then + log_err "Redis не запустился за 15 секунд" + exit 1 + fi sleep 1 done log_ok "Redis готов" @@ -281,6 +399,9 @@ for i in $(seq 1 15); do if docker compose exec -T pgbouncer pg_isready -h 127.0.0.1 -p 6432 &>/dev/null; then break fi + if [[ "$i" -eq 15 ]]; then + log_warn "PgBouncer не отвечает — продолжаем без него" + fi sleep 1 done log_ok "PgBouncer готов" @@ -290,7 +411,7 @@ echo -e " Применение миграций..." npx prisma db push --skip-generate 2>&1 | tail -3 log_ok "Схема БД синхронизирована" -# Create MinIO bucket +# Create MinIO bucket (через docker exec если mc не установлен) echo -e " Создание S3 bucket..." sleep 2 if command -v mc &>/dev/null; then @@ -298,7 +419,15 @@ if command -v mc &>/dev/null; then mc mb "local/${S3_BUCKET}" 2>/dev/null || true log_ok "Bucket '${S3_BUCKET}' создан" else - log_warn "MinIO Client (mc) не найден — создай bucket '${S3_BUCKET}' вручную через http://localhost:9001" + # Создание через curl (MinIO S3 API) + if curl -sf -o /dev/null -X PUT "http://localhost:9000/${S3_BUCKET}" \ + -u "${MINIO_USER}:${MINIO_PASS}" 2>/dev/null; then + log_ok "Bucket '${S3_BUCKET}' создан через API" + else + log_warn "Не удалось создать bucket автоматически" + echo -e " Создай вручную: ${CYAN}http://localhost:9001${NC} → Buckets → Create" + echo -e " Логин: ${CYAN}${MINIO_USER}${NC} / пароль в .env" + fi fi # --- Step 6: Done --- @@ -326,6 +455,15 @@ else fi fi +echo "" +echo -e " ${BOLD}Сгенерированные пароли (сохранены в .env):${NC}" +echo -e " ${CYAN}PostgreSQL:${NC} ${PG_PASSWORD}" +echo -e " ${CYAN}MinIO:${NC} ${MINIO_USER} / ${MINIO_PASS}" +if [[ "$MODE" == "1" && -n "${DEV_ACCESS_KEY:-}" ]]; then + echo -e " ${CYAN}DEV_ACCESS_KEY:${NC} ${DEV_ACCESS_KEY}" +fi +echo -e " ${YELLOW}Изменить пароли: отредактируй .env и перезапусти docker compose${NC}" + if [[ -z "$LK_URL" ]]; then echo "" log_warn "LiveKit не настроен — видеозвонки не будут работать."