diff --git a/backend/pyproject.toml b/backend/pyproject.toml index afabe12a..8df3fa61 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -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] diff --git a/backend/uv.lock b/backend/uv.lock index 8bd2a644..1422c133 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -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" }, diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 54fc3668..90632581 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -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).