fix and update
This commit is contained in:
84
install.sh
84
install.sh
@@ -373,6 +373,31 @@ reload_docker_nginx() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ждёт HTTP /health на опубликованном порту api-gateway (127.0.0.1:3000).
|
||||||
|
wait_for_api_gateway_http() {
|
||||||
|
local max_attempts="${1:-60}"
|
||||||
|
local attempt=0
|
||||||
|
while [[ $attempt -lt $max_attempts ]]; do
|
||||||
|
if curl -fsS --max-time 3 http://127.0.0.1:3000/health 2>/dev/null | grep -q '"status"'; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# После recreate api-gateway nginx должен сбросить DNS/keepalive — иначе 502 на старый IP.
|
||||||
|
sync_nginx_after_api_gateway_restart() {
|
||||||
|
docker_nginx_container_running || return 0
|
||||||
|
log "Синхронизация Docker Nginx с api-gateway после пересборки..."
|
||||||
|
wait_for_service "api-gateway" 120 || warn "api-gateway не стал healthy в срок"
|
||||||
|
wait_for_api_gateway_http 90 || warn "api-gateway /health на :3000 не отвечает"
|
||||||
|
sleep 2
|
||||||
|
reload_docker_nginx
|
||||||
|
verify_nginx_reaches_api_gateway 24 5 || warn "Nginx → api-gateway: проверка не прошла, см. docker compose logs nginx api-gateway"
|
||||||
|
}
|
||||||
|
|
||||||
recreate_docker_nginx() {
|
recreate_docker_nginx() {
|
||||||
compose_uses_proxy_profile || return 0
|
compose_uses_proxy_profile || return 0
|
||||||
build_compose_stack_cmd
|
build_compose_stack_cmd
|
||||||
@@ -702,6 +727,17 @@ compose_build_and_up() {
|
|||||||
if [[ "${SKIP_DOCKER_PRUNE:-0}" -ne 1 ]]; then
|
if [[ "${SKIP_DOCKER_PRUNE:-0}" -ne 1 ]]; then
|
||||||
docker_prune_after_rebuild
|
docker_prune_after_rebuild
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local svc
|
||||||
|
for svc in "${services[@]}"; do
|
||||||
|
case "$svc" in
|
||||||
|
api-gateway) sync_nginx_after_api_gateway_restart ;;
|
||||||
|
media-ws)
|
||||||
|
wait_for_service "media-ws" 60
|
||||||
|
reload_docker_nginx
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
action_docker_prune() {
|
action_docker_prune() {
|
||||||
@@ -1944,10 +1980,12 @@ nginx_proxy_headers=" proxy_set_header Host \$host;
|
|||||||
proxy_read_timeout 300s;
|
proxy_read_timeout 300s;
|
||||||
proxy_connect_timeout 75s;"
|
proxy_connect_timeout 75s;"
|
||||||
|
|
||||||
# Встроенный DNS Docker. В docker-режиме nginx обязан перерезолвлять имена
|
# Встроенный DNS Docker. valid=5s + resolver_timeout — баланс между свежим IP и
|
||||||
# бэкенд-контейнеров на каждый запрос — иначе после пересборки контейнера
|
# «Server failure» при кратковременном дауне контейнера во время recreate.
|
||||||
# (новый IP) остаётся закешированный старый адрес и все ответы становятся 502.
|
NGINX_DOCKER_RESOLVER=" resolver 127.0.0.11 ipv6=off valid=5s;
|
||||||
NGINX_DOCKER_RESOLVER=" resolver 127.0.0.11 ipv6=off valid=1s;"
|
resolver_timeout 5s;"
|
||||||
|
NGINX_DOCKER_SERVER_DNS=" resolver 127.0.0.11 ipv6=off valid=5s;
|
||||||
|
resolver_timeout 5s;"
|
||||||
|
|
||||||
# Имя nginx-переменной из ключа апстрима (только [A-Za-z0-9_]).
|
# Имя nginx-переменной из ключа апстрима (только [A-Za-z0-9_]).
|
||||||
nginx_upstream_var() {
|
nginx_upstream_var() {
|
||||||
@@ -2214,14 +2252,19 @@ ${nginx_proxy_headers}
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nginx_docker_server_dns_block() {
|
||||||
|
[[ "$NGINX_MODE" == "docker" ]] && echo "$NGINX_DOCKER_SERVER_DNS" || true
|
||||||
|
}
|
||||||
|
|
||||||
write_nginx_site_frontend() {
|
write_nginx_site_frontend() {
|
||||||
local domain="$1"
|
local domain="$1"
|
||||||
local ssl_type="${2:-none}"
|
local ssl_type="${2:-none}"
|
||||||
local conf http_preamble ssl_block idp_api_block proxy_root
|
local conf http_preamble ssl_block idp_api_block proxy_root server_dns
|
||||||
conf="$(nginx_conf_target frontend)"
|
conf="$(nginx_conf_target frontend)"
|
||||||
proxy_root="$(render_proxy_root frontend)"
|
proxy_root="$(render_proxy_root frontend)"
|
||||||
http_preamble="$(nginx_http_server_preamble "$domain" "$ssl_type")"
|
http_preamble="$(nginx_http_server_preamble "$domain" "$ssl_type")"
|
||||||
idp_api_block="$(build_nginx_idp_api_proxy_block)"
|
idp_api_block="$(build_nginx_idp_api_proxy_block)"
|
||||||
|
server_dns="$(nginx_docker_server_dns_block)"
|
||||||
|
|
||||||
if [[ "$ssl_type" == "none" ]]; then
|
if [[ "$ssl_type" == "none" ]]; then
|
||||||
nginx_write_conf "$conf" <<EOF
|
nginx_write_conf "$conf" <<EOF
|
||||||
@@ -2229,6 +2272,7 @@ server {
|
|||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name ${domain};
|
server_name ${domain};
|
||||||
|
${server_dns}
|
||||||
${idp_api_block}
|
${idp_api_block}
|
||||||
location / {
|
location / {
|
||||||
${proxy_root}
|
${proxy_root}
|
||||||
@@ -2246,6 +2290,7 @@ ${http_preamble}server {
|
|||||||
server_name ${domain};
|
server_name ${domain};
|
||||||
${ssl_block}
|
${ssl_block}
|
||||||
client_max_body_size 50m;
|
client_max_body_size 50m;
|
||||||
|
${server_dns}
|
||||||
${idp_api_block}
|
${idp_api_block}
|
||||||
location / {
|
location / {
|
||||||
${proxy_root}
|
${proxy_root}
|
||||||
@@ -2266,11 +2311,12 @@ EOF
|
|||||||
write_nginx_site_fedcm_apex() {
|
write_nginx_site_fedcm_apex() {
|
||||||
local domain="$1"
|
local domain="$1"
|
||||||
local ssl_type="${2:-none}"
|
local ssl_type="${2:-none}"
|
||||||
local conf http_preamble ssl_block idp_api_block proxy_root
|
local conf http_preamble ssl_block idp_api_block proxy_root server_dns
|
||||||
conf="$(nginx_conf_target fedcm-apex)"
|
conf="$(nginx_conf_target fedcm-apex)"
|
||||||
proxy_root="$(render_proxy_root frontend)"
|
proxy_root="$(render_proxy_root frontend)"
|
||||||
http_preamble="$(nginx_http_server_preamble "$domain" "$ssl_type")"
|
http_preamble="$(nginx_http_server_preamble "$domain" "$ssl_type")"
|
||||||
idp_api_block="$(build_nginx_idp_api_proxy_block)"
|
idp_api_block="$(build_nginx_idp_api_proxy_block)"
|
||||||
|
server_dns="$(nginx_docker_server_dns_block)"
|
||||||
|
|
||||||
if [[ "$ssl_type" == "none" ]]; then
|
if [[ "$ssl_type" == "none" ]]; then
|
||||||
nginx_write_conf "$conf" <<EOF
|
nginx_write_conf "$conf" <<EOF
|
||||||
@@ -2279,6 +2325,7 @@ server {
|
|||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name ${domain};
|
server_name ${domain};
|
||||||
client_max_body_size 50m;
|
client_max_body_size 50m;
|
||||||
|
${server_dns}
|
||||||
${idp_api_block}
|
${idp_api_block}
|
||||||
location / {
|
location / {
|
||||||
${proxy_root}
|
${proxy_root}
|
||||||
@@ -2296,6 +2343,7 @@ ${http_preamble}server {
|
|||||||
server_name ${domain};
|
server_name ${domain};
|
||||||
${ssl_block}
|
${ssl_block}
|
||||||
client_max_body_size 50m;
|
client_max_body_size 50m;
|
||||||
|
${server_dns}
|
||||||
${idp_api_block}
|
${idp_api_block}
|
||||||
location / {
|
location / {
|
||||||
${proxy_root}
|
${proxy_root}
|
||||||
@@ -2516,7 +2564,12 @@ validate_docker_frontend_nginx_config() {
|
|||||||
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
|
||||||
|
local max_attempts="${1:-1}"
|
||||||
|
local delay_sec="${2:-0}"
|
||||||
|
local attempt=0
|
||||||
local body gw_ip
|
local body gw_ip
|
||||||
|
|
||||||
|
while [[ $attempt -lt $max_attempts ]]; do
|
||||||
gw_ip="$(docker_cmd inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' lendry-id-api-gateway 2>/dev/null || true)"
|
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 \
|
body="$(docker_cmd "${COMPOSE_STACK_CMD[@]}" exec -T nginx \
|
||||||
wget -qO- --timeout=5 http://lendry-id-api-gateway:3000/health 2>/dev/null || true)"
|
wget -qO- --timeout=5 http://lendry-id-api-gateway:3000/health 2>/dev/null || true)"
|
||||||
@@ -2524,7 +2577,13 @@ verify_nginx_reaches_api_gateway() {
|
|||||||
ok "Docker Nginx → lendry-id-api-gateway:3000/health OK (IP api-gateway: ${gw_ip:-?})"
|
ok "Docker Nginx → lendry-id-api-gateway:3000/health OK (IP api-gateway: ${gw_ip:-?})"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
warn "Docker Nginx не достучался до lendry-id-api-gateway:3000 (IP: ${gw_ip:-?})"
|
attempt=$((attempt + 1))
|
||||||
|
if [[ $attempt -lt $max_attempts ]]; then
|
||||||
|
[[ "$delay_sec" -gt 0 ]] && sleep "$delay_sec"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
warn "Docker Nginx не достучался до lendry-id-api-gateway:3000 (IP: ${gw_ip:-?}, попыток: ${max_attempts})"
|
||||||
warn "Проверьте: docker compose ps api-gateway && docker compose logs --tail=40 api-gateway"
|
warn "Проверьте: docker compose ps api-gateway && docker compose logs --tail=40 api-gateway"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -2786,6 +2845,7 @@ deploy_stack() {
|
|||||||
|
|
||||||
wait_for_service "sso-core" 120
|
wait_for_service "sso-core" 120
|
||||||
wait_for_service "api-gateway" 90
|
wait_for_service "api-gateway" 90
|
||||||
|
sync_nginx_after_api_gateway_restart
|
||||||
wait_for_service "frontend" 60
|
wait_for_service "frontend" 60
|
||||||
wait_for_service "docs" 60
|
wait_for_service "docs" 60
|
||||||
if compose_uses_proxy_profile; then
|
if compose_uses_proxy_profile; then
|
||||||
@@ -3345,6 +3405,7 @@ action_fix_host_proxy() {
|
|||||||
compose_build_and_up api-gateway
|
compose_build_and_up api-gateway
|
||||||
wait_for_service "api-gateway" 90
|
wait_for_service "api-gateway" 90
|
||||||
wait_for_api_grpc_ready 60 || true
|
wait_for_api_grpc_ready 60 || true
|
||||||
|
sync_nginx_after_api_gateway_restart
|
||||||
|
|
||||||
ok "Прокси исправлен — проверьте: curl -I http://127.0.0.1:3002"
|
ok "Прокси исправлен — проверьте: curl -I http://127.0.0.1:3002"
|
||||||
diagnose_common_issues || true
|
diagnose_common_issues || true
|
||||||
@@ -3379,6 +3440,7 @@ action_fix_all_errors() {
|
|||||||
compose_build_and_up api-gateway
|
compose_build_and_up api-gateway
|
||||||
wait_for_service "api-gateway" 90
|
wait_for_service "api-gateway" 90
|
||||||
wait_for_api_grpc_ready 90 || compose_build_and_up api-gateway
|
wait_for_api_grpc_ready 90 || compose_build_and_up api-gateway
|
||||||
|
sync_nginx_after_api_gateway_restart
|
||||||
|
|
||||||
log "Шаг 4/6: пересборка frontend (same-origin /idp-api), docs, media-ws..."
|
log "Шаг 4/6: пересборка frontend (same-origin /idp-api), docs, media-ws..."
|
||||||
compose_build_and_up frontend docs media-ws
|
compose_build_and_up frontend docs media-ws
|
||||||
@@ -3407,10 +3469,12 @@ action_fix_all_errors() {
|
|||||||
esac
|
esac
|
||||||
apply_intranet_selfsigned_runtime
|
apply_intranet_selfsigned_runtime
|
||||||
recreate_docker_nginx
|
recreate_docker_nginx
|
||||||
verify_nginx_reaches_api_gateway || compose_build_and_up api-gateway
|
sync_nginx_after_api_gateway_restart
|
||||||
|
verify_nginx_reaches_api_gateway 24 5 || compose_build_and_up api-gateway
|
||||||
|
sync_nginx_after_api_gateway_restart
|
||||||
verify_nginx_reaches_media_ws || compose_build_and_up media-ws
|
verify_nginx_reaches_media_ws || compose_build_and_up media-ws
|
||||||
recreate_docker_nginx
|
reload_docker_nginx
|
||||||
verify_nginx_reaches_api_gateway || fail "Nginx не проксирует на api-gateway — см. docker compose logs nginx api-gateway"
|
verify_nginx_reaches_api_gateway 24 5 || fail "Nginx не проксирует на api-gateway — см. docker compose logs nginx api-gateway"
|
||||||
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"
|
||||||
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"
|
||||||
|
|||||||
Reference in New Issue
Block a user