chore(infra): correct frontend healthcheck (re-apply #117 safely) #120

Merged
lekss361 merged 1 commit from fix/frontend-healthcheck-correct into main 2026-05-14 20:24:47 +00:00
3 changed files with 23 additions and 7 deletions

View file

@ -28,7 +28,7 @@ dependencies = [
"numpy>=2.0.0",
"scikit-learn>=1.5.0",
"sentry-sdk[fastapi]>=2.10.0",
"rosreestr2coord>=4.0.0",
"rosreestr2coord>=5.0.0",
]
[dependency-groups]

2
backend/uv.lock generated
View file

@ -616,7 +616,7 @@ requires-dist = [
{ name = "pydantic-settings", specifier = ">=2.3.0" },
{ name = "pyproj", specifier = ">=3.6.0" },
{ name = "redis", specifier = ">=5.0.0" },
{ name = "rosreestr2coord", specifier = ">=4.0.0" },
{ name = "rosreestr2coord", specifier = ">=5.0.0" },
{ name = "scikit-learn", specifier = ">=1.5.0" },
{ name = "sentry-sdk", extras = ["fastapi"], specifier = ">=2.10.0" },
{ name = "shapely", specifier = ">=2.0.0" },

View file

@ -58,7 +58,7 @@ services:
postgres:
condition: service_healthy
redis:
condition: service_started
condition: service_healthy
ports:
- "127.0.0.1:8000:8000"
healthcheck:
@ -75,6 +75,16 @@ services:
- "127.0.0.1:3000:3000"
depends_on:
- backend
# TCP-only probe через node (есть в alpine image, запускает сам server.js).
# НЕ использует HTTP semantics — проверяет только что порт 3000 слушает.
# Если Next.js процесс жив и порт открыт → healthy, независимо от HTTP status.
# start_period 60s даёт время Next.js standalone bundle bootstrap.
healthcheck:
test: ["CMD", "node", "-e", "require('net').createConnection({port:3000,host:'127.0.0.1'}).once('connect',function(){process.exit(0)}).once('error',function(){process.exit(1)})"]
interval: 15s
timeout: 5s
retries: 6
start_period: 60s
worker:
# Отдельный chromium-образ (+200 МБ Playwright). См. backend/Dockerfile target=runner-with-chromium.
@ -88,7 +98,7 @@ services:
postgres:
condition: service_healthy
redis:
condition: service_started
condition: service_healthy
volumes:
- ./data:/app/data # playwright_state.json + photo binaries
# Read-only bind-mount Антоновского /sf/ SQLite — для objective_etl task.
@ -108,7 +118,7 @@ services:
required: false
depends_on:
redis:
condition: service_started
condition: service_healthy
command: ["celery", "-A", "app.workers.celery_app", "beat", "--loglevel=info"]
caddy:
@ -121,9 +131,15 @@ services:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
# backend: service_healthy — backend имеет /health endpoint, готов до Caddy.
# frontend: service_started — НЕ service_healthy: даже если frontend healthcheck
# дребезжит, Caddy всё равно стартует (можно отдавать 502 для /, но
# obsidian.gendsgn.ru, api.gendsgn.ru и т.д. остаются доступны).
depends_on:
- backend
- frontend
backend:
condition: service_healthy
frontend:
condition: service_started
networks:
- default
# shared — для маршрута obsidian.gendsgn.ru → couchdb (отдельный stack).