From d312e76abb8c27538293205cbb6df50d392b962b Mon Sep 17 00:00:00 2001 From: lendry Date: Mon, 29 Jun 2026 19:26:52 +0300 Subject: [PATCH] fix and update --- install.sh | 97 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/install.sh b/install.sh index b204cc8..4845ca9 100644 --- a/install.sh +++ b/install.sh @@ -10,7 +10,7 @@ set -euo pipefail -SCRIPT_VERSION="2.3.4" +SCRIPT_VERSION="2.3.5" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$ROOT_DIR" @@ -373,6 +373,14 @@ reload_docker_nginx() { fi } +recreate_docker_nginx() { + compose_uses_proxy_profile || return 0 + build_compose_stack_cmd + log "Пересоздание контейнера lendry-id-nginx (подхват конфигов из ./nginx/conf.d)..." + docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --force-recreate nginx + wait_for_service "nginx" 60 +} + prepare_compose_stack() { resolve_nginx_mode_and_ports write_compose_override @@ -1521,7 +1529,8 @@ ensure_host_upstreams() { nginx_upstream() { case "$1" in api) - [[ "$NGINX_MODE" == "docker" ]] && echo "http://api-gateway:3000" || echo "http://127.0.0.1:3000" + # container_name стабильнее service name при пересоздании compose-стека + [[ "$NGINX_MODE" == "docker" ]] && echo "http://lendry-id-api-gateway:3000" || echo "http://127.0.0.1:3000" ;; frontend) [[ "$NGINX_MODE" == "docker" ]] && echo "http://frontend:3000" || echo "http://127.0.0.1:3002" @@ -2378,8 +2387,57 @@ remove_nginx_configs() { ok "Конфиги Nginx IdP удалены" } -write_all_nginx_configs() { +# Перед записью конфигов: docker-режим если lendry-id-nginx или FORCE_DOCKER / NGINX_MODE=docker в .env +ensure_nginx_mode_for_config_write() { load_env + if [[ "${FORCE_DOCKER_NGINX:-0}" -eq 1 ]] \ + || [[ "$(env_get NGINX_MODE auto)" == "docker" ]] \ + || docker_nginx_container_running; then + NGINX_MODE="docker" + env_set NGINX_MODE "docker" + elif [[ -n "$(env_get NGINX_MODE "")" && "$(env_get NGINX_MODE auto)" != "auto" ]]; then + NGINX_MODE="$(env_get NGINX_MODE auto)" + else + detect_nginx_mode + fi + log "Запись конфигов Nginx: mode=${NGINX_MODE}, каталог=${LOCAL_CONF_DIR}" +} + +validate_docker_api_nginx_config() { + [[ "$NGINX_MODE" == "docker" ]] || return 0 + local conf="${LOCAL_CONF_DIR}/${NGINX_PREFIX}-api.conf" + [[ -f "$conf" ]] || fail "Не найден ${conf} — конфиг API-домена не записан" + + if grep -q "upstream ${NGINX_PREFIX}_api" "$conf" 2>/dev/null; then + fail "Конфиг ${conf} содержит static upstream — обновите install.sh и выполните ./install.sh --fix-all" + fi + if ! grep -q 'resolver 127.0.0.11' "$conf" 2>/dev/null; then + fail "Конфиг ${conf} без resolver 127.0.0.11 — API-домен не переживёт пересборку api-gateway" + fi + if ! grep -q 'idp_up_api' "$conf" 2>/dev/null; then + fail "Конфиг ${conf} без динамического proxy_pass — выполните ./install.sh --fix-all" + fi + ok "Конфиг API-домена: динамический DNS (resolver + idp_up_api)" +} + +verify_nginx_reaches_api_gateway() { + docker_nginx_container_running || return 0 + build_compose_stack_cmd + local body gw_ip + gw_ip="$(docker_cmd inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' lendry-id-api-gateway 2>/dev/null || true)" + body="$(docker_cmd "${COMPOSE_STACK_CMD[@]}" exec -T nginx \ + wget -qO- --timeout=5 http://lendry-id-api-gateway:3000/health 2>/dev/null || true)" + if [[ "$body" == *'"status":"ok"'* ]] || [[ "$body" == *'"status": "ok"'* ]]; then + ok "Docker Nginx → lendry-id-api-gateway:3000/health OK (IP api-gateway: ${gw_ip:-?})" + return 0 + fi + warn "Docker Nginx не достучался до lendry-id-api-gateway:3000 (IP: ${gw_ip:-?})" + warn "Проверьте: docker compose ps api-gateway && docker compose logs --tail=40 api-gateway" + return 1 +} + +write_all_nginx_configs() { + ensure_nginx_mode_for_config_write local ssl_type="${1:-$(env_get SSL_TYPE none)}" local ws_on_api="true" [[ -n "${DOMAIN_WS:-}" && "${DOMAIN_WS}" != "${DOMAIN_API}" ]] && ws_on_api="false" @@ -2414,6 +2472,8 @@ write_all_nginx_configs() { [[ -n "${DOMAIN_MINIO:-}" ]] && write_nginx_site_minio "$DOMAIN_MINIO" minio minio "$ssl_type" [[ -n "${DOMAIN_MINIO_CONSOLE:-}" ]] && write_nginx_site_minio "$DOMAIN_MINIO_CONSOLE" minio-console minio-console "$ssl_type" + validate_docker_api_nginx_config + if [[ "$NGINX_MODE" == "host" ]]; then if run_root nginx -t; then run_root systemctl reload nginx || warn "Не удалось перезагрузить Nginx (systemctl reload nginx)" @@ -2746,6 +2806,22 @@ check_https_api_with_origin() { return 1 fi + code="$(curl -sk --max-time 5 -o /dev/null -w '%{http_code}' -X OPTIONS \ + -H "Origin: ${origin}" \ + -H "Access-Control-Request-Method: GET" \ + "https://${api_domain}/notifications/unread-count" 2>/dev/null || echo 000)" + if [[ "$code" == "204" || "$code" == "200" ]]; then + echo -e " ${GREEN}✔${NC} HTTPS API preflight (OPTIONS): /notifications/unread-count → ${code}" + elif [[ "$code" == "502" ]]; then + echo -e " ${RED}✘${NC} HTTPS API preflight (OPTIONS) → 502 — Nginx не достучался до api-gateway" + echo " Проверьте: grep resolver nginx/conf.d/lendry-id-api.conf" + echo " docker compose --profile proxy exec nginx wget -qO- http://lendry-id-api-gateway:3000/health" + return 1 + else + echo -e " ${YELLOW}!${NC} HTTPS API preflight (OPTIONS) → HTTP ${code} (ожидалось 204)" + return 1 + fi + local test_token test_token="$(env_get IDP_TEST_BEARER_TOKEN "")" if [[ -n "$test_token" ]]; then @@ -3131,7 +3207,9 @@ action_fix_all_errors() { write_compose_override ensure_split_domain_public_urls - log "Шаг 3/6: пересборка sso-core, затем api-gateway..." + log "Шаг 3/6: пересборка ldap-auth → sso-core → api-gateway..." + compose_build_and_up ldap-auth + wait_for_service "ldap-auth" 90 compose_build_and_up sso-core wait_for_service "sso-core" 120 compose_build_and_up api-gateway @@ -3161,17 +3239,18 @@ action_fix_all_errors() { ;; esac apply_intranet_selfsigned_runtime - compose_build_and_up nginx ldap-auth - wait_for_service "nginx" 45 - reload_docker_nginx - wait_for_api_grpc_ready 30 || true + recreate_docker_nginx + verify_nginx_reaches_api_gateway || compose_build_and_up api-gateway + recreate_docker_nginx + verify_nginx_reaches_api_gateway || fail "Nginx не проксирует на api-gateway — см. docker compose logs nginx api-gateway" if ! docker_nginx_container_running; then fail "Контейнер lendry-id-nginx не запущен. Проверьте: docker compose --profile proxy logs nginx" fi ok "Docker Nginx запущен — проверьте: docker ps | grep lendry-id-nginx" - log "Шаг 6/6: финальная проверка..." + log "Шаг 6/6: финальная проверка (HTTPS + CORS preflight)..." diagnose_common_issues || true + check_https_api_with_origin || warn "Проверка cross-origin API не прошла — см. вывод выше" ok "Исправление завершено" echo ""