fix: remove "type" field from package.json + improve setup.sh
- 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 <noreply@anthropic.com>
This commit is contained in:
214
setup.sh
214
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 не настроен — видеозвонки не будут работать."
|
||||
|
||||
Reference in New Issue
Block a user