fix and update

This commit is contained in:
lendry
2026-06-30 17:30:07 +03:00
parent ac9f405f43
commit 521de7ea00

View File

@@ -2150,11 +2150,38 @@ render_proxy_rewrite() {
printf ' rewrite ^.*$ %s break;\n proxy_pass %s;' "$target" "$up" printf ' rewrite ^.*$ %s break;\n proxy_pass %s;' "$target" "$up"
} }
# proxy_pass для /idp-api/ — prefix ^~ выше regex; rewrite снимает префикс перед api-gateway. # proxy_pass для /idp-api/ — trailing slash снимает префикс без rewrite (надёжнее под HTTP/2).
render_proxy_idp_api() { render_proxy_idp_api() {
local up local up
up="$(nginx_upstream api)" up="$(nginx_upstream api)"
printf ' rewrite ^/idp-api/?(.*)$ /$1 break;\n proxy_pass %s;' "$up" printf ' proxy_pass %s/;' "$up"
}
# WebSocket /idp-api/ws → media-ws /ws (без rewrite break).
render_proxy_idp_ws() {
local up
up="$(nginx_upstream ws)"
printf ' proxy_pass %s/ws;' "$up"
}
# Старые конфиги с $request_uri дают 502 «no resolver defined» на location /.
patch_legacy_nginx_proxy_pass() {
[[ "$NGINX_MODE" == "docker" ]] || return 0
local conf patched=0
shopt -s nullglob
for conf in "${LOCAL_CONF_DIR}/${NGINX_PREFIX}-"*.conf; do
[[ -f "$conf" ]] || continue
if grep -q 'proxy_pass.*\$request_uri' "$conf" 2>/dev/null; then
log "Патч legacy proxy_pass \$request_uri → $(basename "$conf")"
sed -i -E 's|proxy_pass (http://[^;]+)\$request_uri;|proxy_pass \1;|g' "$conf"
patched=1
fi
done
shopt -u nullglob
if [[ $patched -eq 1 ]]; then
ok "Legacy proxy_pass \$request_uri исправлен в nginx/conf.d"
reload_docker_nginx || true
fi
} }
nginx_write_conf() { nginx_write_conf() {
@@ -2327,7 +2354,7 @@ EOF
build_nginx_idp_api_proxy_block() { build_nginx_idp_api_proxy_block() {
local proxy_ws proxy_idp proxy_oauth proxy_wk proxy_fedcm local proxy_ws proxy_idp proxy_oauth proxy_wk proxy_fedcm
proxy_ws="$(render_proxy_rewrite ws /ws)" proxy_ws="$(render_proxy_idp_ws)"
proxy_idp="$(render_proxy_idp_api)" proxy_idp="$(render_proxy_idp_api)"
proxy_oauth="$(render_proxy_root api)" proxy_oauth="$(render_proxy_root api)"
proxy_wk="$(render_proxy_root api)" proxy_wk="$(render_proxy_root api)"
@@ -2371,7 +2398,13 @@ EOF
} }
nginx_docker_server_dns_block() { nginx_docker_server_dns_block() {
return 0 if [[ "$NGINX_MODE" != "docker" ]]; then
return 0
fi
cat <<'EOF'
# Docker embedded DNS — страховка для variable proxy_pass и после recreate контейнеров.
resolver 127.0.0.11 valid=10s ipv6=off;
EOF
} }
write_nginx_site_frontend() { write_nginx_site_frontend() {
@@ -2672,15 +2705,25 @@ validate_docker_frontend_nginx_config() {
if ! grep -q 'lendry-id-api-gateway:3000' "$conf" 2>/dev/null; then if ! grep -q 'lendry-id-api-gateway:3000' "$conf" 2>/dev/null; then
fail "Конфиг ${conf} без proxy_pass на lendry-id-api-gateway:3000 — выполните ./install.sh --fix-all" fail "Конфиг ${conf} без proxy_pass на lendry-id-api-gateway:3000 — выполните ./install.sh --fix-all"
fi fi
if grep -q 'proxy_pass http://lendry-id-frontend:3000\$request_uri' "$conf" 2>/dev/null; then
fail "Конфиг ${conf}: proxy_pass с \$request_uri на frontend — 502 «no resolver defined». Выполните ./install.sh --fix-all"
fi
if ! grep -q 'location \^~ /idp-api/ws' "$conf" 2>/dev/null; then if ! grep -q 'location \^~ /idp-api/ws' "$conf" 2>/dev/null; then
warn "Конфиг ${conf}: location ^~ /idp-api/ws отсутствует — WebSocket может идти на api-gateway вместо media-ws" warn "Конфиг ${conf}: location ^~ /idp-api/ws отсутствует — WebSocket может идти на api-gateway вместо media-ws"
fi fi
ok "Конфиг SSO-домена: /idp-api → lendry-id-api-gateway:3000" ok "Конфиг SSO-домена: /idp-api → lendry-id-api-gateway:3000"
} }
validate_all_docker_nginx_proxy_pass() {
[[ "$NGINX_MODE" == "docker" ]] || return 0
local conf
shopt -s nullglob
for conf in "${LOCAL_CONF_DIR}/${NGINX_PREFIX}-"*.conf; do
[[ -f "$conf" ]] || continue
if grep -q 'proxy_pass.*\$request_uri' "$conf" 2>/dev/null; then
fail "Конфиг $(basename "$conf") содержит proxy_pass \$request_uri — 502 «no resolver defined» на /. Выполните ./install.sh --fix-all"
fi
done
shopt -u nullglob
}
verify_nginx_reaches_api_gateway() { verify_nginx_reaches_api_gateway() {
docker_nginx_container_running || return 0 docker_nginx_container_running || return 0
build_compose_stack_cmd build_compose_stack_cmd
@@ -2709,7 +2752,7 @@ verify_nginx_reaches_api_gateway() {
return 1 return 1
} }
# Тот же путь, что в браузере: location ^~ /idp-api/ + rewrite + proxy_pass $idp_up_api # Тот же путь, что в браузере: location ^~ /idp-api/ → api-gateway.
verify_nginx_idp_api_location() { verify_nginx_idp_api_location() {
docker_nginx_container_running || return 0 docker_nginx_container_running || return 0
load_env load_env
@@ -2893,6 +2936,34 @@ check_sso_idp_api_proxy() {
fi fi
} }
# Несколько подряд проб /idp-api/health — ловит «curl OK, браузер 502» после recreate контейнеров.
verify_sso_idp_api_burst() {
load_env
local frontend_domain="$1" ssl_type i code ok_count=0
frontend_domain="${frontend_domain:-$(env_get DOMAIN_FRONTEND "")}"
[[ -n "$frontend_domain" ]] || return 0
ssl_type="$(env_get SSL_TYPE none)"
for i in 1 2 3 4 5; do
if [[ "$(env_get USE_NGINX_SSL false)" == "true" || "$ssl_type" != "none" ]]; then
code="$(curl -sk --max-time 4 -o /dev/null -w '%{http_code}' "https://${frontend_domain}/idp-api/health" 2>/dev/null || echo 000)"
else
code="$(curl -fsS --max-time 4 -o /dev/null -w '%{http_code}' "http://${frontend_domain}/idp-api/health" 2>/dev/null || echo 000)"
fi
[[ "$code" == "200" ]] && ok_count=$((ok_count + 1))
sleep 0.25
done
if [[ $ok_count -ge 4 ]]; then
ok "SSO /idp-api/health стабилен (${ok_count}/5 → 200)"
return 0
fi
warn "SSO /idp-api/health нестабилен (${ok_count}/5 → 200) — возможны 502 в браузере"
warn "Выполните: docker compose --env-file .env --profile proxy exec nginx nginx -s reload"
return 1
}
write_all_nginx_configs() { write_all_nginx_configs() {
ensure_nginx_mode_for_config_write ensure_nginx_mode_for_config_write
local ssl_type="${1:-$(env_get SSL_TYPE none)}" local ssl_type="${1:-$(env_get SSL_TYPE none)}"
@@ -2931,6 +3002,7 @@ write_all_nginx_configs() {
validate_docker_api_nginx_config validate_docker_api_nginx_config
validate_docker_frontend_nginx_config validate_docker_frontend_nginx_config
validate_all_docker_nginx_proxy_pass
if [[ "$NGINX_MODE" == "host" ]]; then if [[ "$NGINX_MODE" == "host" ]]; then
if run_root nginx -t; then if run_root nginx -t; then
@@ -3341,6 +3413,15 @@ diagnose_common_issues() {
else else
echo -e " ${GREEN}${NC} Docker Nginx: запущен (режим docker)" echo -e " ${GREEN}${NC} Docker Nginx: запущен (режим docker)"
fi fi
if [[ "$(env_get NGINX_MODE docker)" == "docker" ]]; then
shopt -s nullglob
if grep -q 'proxy_pass.*\$request_uri' "${LOCAL_CONF_DIR}/${NGINX_PREFIX}-"*.conf 2>/dev/null; then
echo -e " ${RED}${NC} nginx/conf.d: proxy_pass \$request_uri — 502 на / (no resolver defined to resolve lendry-id-frontend)"
echo " Решение: ./install.sh --fix-all"
issues=$((issues + 1))
fi
shopt -u nullglob
fi
elif [[ "$(env_get NGINX_MODE docker)" == "docker" ]] && compose_uses_proxy_profile; then elif [[ "$(env_get NGINX_MODE docker)" == "docker" ]] && compose_uses_proxy_profile; then
echo -e " ${YELLOW}!${NC} Docker Nginx не запущен (ожидался в режиме docker)" echo -e " ${YELLOW}!${NC} Docker Nginx не запущен (ожидался в режиме docker)"
issues=$((issues + 1)) issues=$((issues + 1))
@@ -3786,6 +3867,8 @@ action_fix_all_errors() {
log "frontend NEXT_PUBLIC_API_URL=${baked_api:-не задан} (браузер SPA использует /idp-api на SSO)" log "frontend NEXT_PUBLIC_API_URL=${baked_api:-не задан} (браузер SPA использует /idp-api на SSO)"
log "Шаг 5/6: Docker Nginx — конфиги в ./nginx/conf.d и контейнер lendry-id-nginx..." log "Шаг 5/6: Docker Nginx — конфиги в ./nginx/conf.d и контейнер lendry-id-nginx..."
ensure_nginx_gateway_watch_script
patch_legacy_nginx_proxy_pass
local ssl_type local ssl_type
ssl_type="$(env_get SSL_TYPE none)" ssl_type="$(env_get SSL_TYPE none)"
case "$ssl_type" in case "$ssl_type" in
@@ -3814,6 +3897,7 @@ action_fix_all_errors() {
verify_nginx_reaches_frontend 12 3 || fail "Nginx не проксирует / на frontend — см. docker compose logs nginx frontend" verify_nginx_reaches_frontend 12 3 || fail "Nginx не проксирует / на frontend — см. docker compose logs nginx frontend"
check_sso_idp_api_proxy || fail "SSO /idp-api/health недоступен — см. nginx/conf.d/${NGINX_PREFIX}-frontend.conf" check_sso_idp_api_proxy || fail "SSO /idp-api/health недоступен — см. nginx/conf.d/${NGINX_PREFIX}-frontend.conf"
check_sso_frontend_root || fail "SSO / → 502 — главная страница недоступна (502 Bad Gateway в браузере)" check_sso_frontend_root || fail "SSO / → 502 — главная страница недоступна (502 Bad Gateway в браузере)"
verify_sso_idp_api_burst || warn "Нестабильный /idp-api/health — при 502 в браузере: docker compose --profile proxy exec nginx nginx -s reload"
if ! docker_nginx_container_running; then if ! docker_nginx_container_running; then
fail "Контейнер lendry-id-nginx не запущен. Проверьте: docker compose --profile proxy logs nginx" fail "Контейнер lendry-id-nginx не запущен. Проверьте: docker compose --profile proxy logs nginx"
fi fi