From 4cae7b48ef3fbceab475f2cf08456955ce3b48a9 Mon Sep 17 00:00:00 2001 From: joylessorchid Date: Tue, 24 Mar 2026 03:29:18 +0300 Subject: [PATCH] fix: pgbouncer healthcheck + minio doctor checks via docker exec - pgbouncer: replace pg_isready with nc (not available in edoburu/pgbouncer) - minio: add healthcheck in docker-compose.yml - doctor: check minio/pgbouncer via docker exec instead of localhost curl - cmd_dev: wait for healthy services, auto-create minio bucket --- docker-compose.yml | 7 ++- setup.sh | 107 ++++++++++++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 31 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c4418ab..0d29973 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,6 +39,11 @@ services: MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin} volumes: - minio_data:/data + healthcheck: + test: ["CMD-SHELL", "curl -sf http://localhost:9000/minio/health/live || exit 1"] + interval: 10s + timeout: 5s + retries: 3 restart: unless-stopped redis: @@ -63,7 +68,7 @@ services: DEFAULT_POOL_SIZE: 25 MIN_POOL_SIZE: 5 healthcheck: - test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 6432"] + test: ["CMD-SHELL", "sh -c 'echo | nc -w 2 127.0.0.1 6432'"] interval: 5s timeout: 3s retries: 5 diff --git a/setup.sh b/setup.sh index 096708f..b8f921b 100644 --- a/setup.sh +++ b/setup.sh @@ -556,10 +556,10 @@ cmd_doctor() { # PgBouncer if [[ "$(check_service pgbouncer)" == "ok" ]]; then - if docker compose exec -T pgbouncer pg_isready -h 127.0.0.1 -p 6432 &>/dev/null; then - log_ok "PgBouncer: подключение OK" + if docker compose exec -T pgbouncer sh -c 'echo | nc -w 2 127.0.0.1 6432' &>/dev/null; then + log_ok "PgBouncer: порт 6432 отвечает" else - log_warn "PgBouncer: не отвечает через pg_isready" + log_warn "PgBouncer: порт 6432 не отвечает" issues=$((issues + 1)) fi fi @@ -593,7 +593,6 @@ cmd_doctor() { if [[ "$(check_service minio)" == "ok" ]]; then log_ok "MinIO контейнер запущен" - local s3_endpoint="http://localhost:9000" local minio_user minio_user=$(env_get MINIO_ROOT_USER) local minio_pass @@ -602,32 +601,32 @@ cmd_doctor() { bucket=$(env_get S3_BUCKET) bucket="${bucket:-liveserver}" - # Проверить healthcheck - if curl -sf -o /dev/null "${s3_endpoint}/minio/health/live" 2>/dev/null; then + # Проверить healthcheck через docker exec (не зависит от пробросa портов) + if docker compose exec -T minio curl -sf http://localhost:9000/minio/health/live &>/dev/null; then log_ok "MinIO health: live" else - log_warn "MinIO health endpoint не отвечает (может быть закрыт порт)" + log_warn "MinIO health endpoint не отвечает" issues=$((issues + 1)) fi - # Проверить bucket - local bucket_check - bucket_check=$(curl -sf -o /dev/null -w "%{http_code}" "${s3_endpoint}/${bucket}/" -u "${minio_user}:${minio_pass}" 2>/dev/null || echo "000") - if [[ "$bucket_check" == "200" || "$bucket_check" == "404" ]]; then - # 404 от bucket listing может быть нормально если нет объектов - log_ok "MinIO: bucket '${bucket}' доступен" - else - log_warn "MinIO: bucket '${bucket}' недоступен (HTTP ${bucket_check})" - issues=$((issues + 1)) - log_fix "Создаю bucket..." - if check_command mc; then - mc alias set local "${s3_endpoint}" "$minio_user" "$minio_pass" 2>/dev/null || true - mc mb "local/${bucket}" 2>/dev/null || true - fixed=$((fixed + 1)) + # Проверить/создать bucket через docker exec mc + if docker compose exec -T minio mc alias set local http://localhost:9000 "$minio_user" "$minio_pass" &>/dev/null; then + if docker compose exec -T minio mc ls "local/${bucket}" &>/dev/null; then + log_ok "MinIO: bucket '${bucket}' существует" else - curl -sf -o /dev/null -X PUT "${s3_endpoint}/${bucket}" -u "${minio_user}:${minio_pass}" 2>/dev/null && fixed=$((fixed + 1)) || \ - log_warn "Создай вручную: http://localhost:9001" + log_warn "MinIO: bucket '${bucket}' не найден" + issues=$((issues + 1)) + log_fix "Создаю bucket..." + if docker compose exec -T minio mc mb "local/${bucket}" &>/dev/null; then + log_ok "Bucket '${bucket}' создан" + fixed=$((fixed + 1)) + else + log_warn "Не удалось создать bucket" + fi fi + else + log_warn "MinIO: mc недоступен в контейнере — проверка bucket пропущена" + issues=$((issues + 1)) fi else log_err "MinIO не запущен" @@ -1276,7 +1275,7 @@ cmd_dev() { log_step "Dev Server — обновление и запуск" # 1. Git pull (без интерактива — stash автоматически) - log_step "1/6 — Обновление кода" + log_step "1/7 — Обновление кода" if [[ -d .git ]]; then if ! git diff --quiet 2>/dev/null || ! git diff --cached --quiet 2>/dev/null; then git stash push -m "auto-stash before dev $(date +%Y%m%d_%H%M%S)" 2>&1 @@ -1286,13 +1285,13 @@ cmd_dev() { log_ok "git pull завершён" fi - # 2. npm install (только если package-lock изменился) - log_step "2/6 — Зависимости" + # 2. npm install + log_step "2/7 — Зависимости" npm install 2>&1 | tail -3 log_ok "npm install завершён" # 3. Prisma - log_step "3/6 — Prisma" + log_step "3/7 — Prisma" npx prisma generate 2>&1 | tail -2 if docker compose exec -T postgres pg_isready -U postgres &>/dev/null; then npx prisma db push --skip-generate --accept-data-loss 2>&1 | tail -3 @@ -1302,12 +1301,37 @@ cmd_dev() { fi # 4. Инфраструктурные контейнеры - log_step "4/6 — Контейнеры" + log_step "4/7 — Контейнеры" docker compose up -d postgres minio redis pgbouncer 2>&1 | tail -5 log_ok "Инфра-контейнеры запущены" + # Ждём здоровья сервисов (макс 30 сек) + log_info "Ожидаю готовности сервисов..." + local waited=0 + while [[ $waited -lt 30 ]]; do + local all_ok=true + for svc in postgres redis pgbouncer; do + local st + st=$(check_service "$svc") + if [[ "$st" != "ok" ]]; then + all_ok=false + break + fi + done + if $all_ok; then + log_ok "Все сервисы healthy" + break + fi + sleep 2 + waited=$((waited + 2)) + done + if [[ $waited -ge 30 ]]; then + log_warn "Таймаут ожидания — некоторые сервисы могут быть unhealthy" + log_info "Запусти ./setup.sh doctor для диагностики" + fi + # 5. Убить старые процессы Next.js - log_step "5/6 — Очистка старых процессов" + log_step "5/7 — Очистка старых процессов" local killed=0 for pid in $(pgrep -f "next dev" 2>/dev/null || true); do kill "$pid" 2>/dev/null && ((killed++)) || true @@ -1326,10 +1350,33 @@ cmd_dev() { fi # 6. Очистка .next кеша - log_step "6/6 — Очистка кеша" + log_step "6/7 — Очистка кеша" [[ -d ".next" ]] && rm -rf .next log_ok "Кеш очищен" + # 7. MinIO bucket + log_step "7/7 — MinIO bucket" + local bucket + bucket=$(env_get S3_BUCKET) + bucket="${bucket:-liveserver}" + local minio_user + minio_user=$(env_get MINIO_ROOT_USER) + minio_user="${minio_user:-minioadmin}" + local minio_pass + minio_pass=$(env_get MINIO_ROOT_PASSWORD) + minio_pass="${minio_pass:-minioadmin}" + if docker compose exec -T minio mc alias set local http://localhost:9000 "$minio_user" "$minio_pass" &>/dev/null; then + if docker compose exec -T minio mc ls "local/${bucket}" &>/dev/null; then + log_ok "Bucket '${bucket}' существует" + else + docker compose exec -T minio mc mb "local/${bucket}" &>/dev/null && \ + log_ok "Bucket '${bucket}' создан" || \ + log_warn "Не удалось создать bucket — создай вручную: http://localhost:9001" + fi + else + log_warn "MinIO ещё не готов — bucket создастся при следующем запуске" + fi + # Автоопределение LAN IP для auth local lan_ip lan_ip=$(hostname -I 2>/dev/null | awk '{print $1}' || true)