docker-compose.vps-2c8g.yml
Rama main · réplica de lectura del repositorio original.
#
# VPS overlay tuned for small machines (2 CPU / 8 GB RAM).
#
# Usage:
# docker compose \
# -f docker-compose.yml \
# -f docker-compose.prod.yml \
# -f docker-compose.vps-2c8g.yml \
# --env-file .env.prod up -d --compatibility
#
# Scope note: this overlay gates exactly ONE service. That is not an oversight —
# see the kafka-mcp-sink and kafka-connect notes below. Everything else the CDC
# plane costs is either load-bearing for batch or cannot be removed without
# manufacturing a worse failure than the RAM it saves.
#
services:
# debezium-mcp is genuinely CDC-only: nothing in a batch pipeline touches it,
# and requiredServices() lists it solely under the isCDC branch
# (backend-orchestrator/internal/workers/infra_preflight.go:176-200).
# Enable with `--profile cdc`.
debezium-mcp:
profiles: ["cdc"]
# kafka-mcp-sink-mcp is deliberately NOT profiled out.
#
# It used to carry `profiles: ["cdc"]`, which broke EVERY batch pipeline on
# this overlay. The sink is not a CDC component: a batch run dispatches its
# rows through it on BOTH lanes — direct-kafka and the MinIO claim-check lane
# (executor/silent_drop_check.go:30-60, "both go through kafka-mcp-sink").
#
# Pre-flight now requires it for batch too (infra_preflight.go
# requiredServices). Before that it was listed only under the isCDC
# branch, so a batch run sailed through pre-flight, shipped
# its rows into Kafka with nothing consuming them, and failed at the reconcile
# deadline with "dispatched N rows via sink but no acks were recorded …
# failing closed as a total drop" (silent_drop_check.go:93). That message
# reads as an unreachable DESTINATION, so it sends you to the wrong end of
# the pipeline entirely.
# kafka-connect is deliberately NOT profiled out either, and this one is a
# trade rather than a requirement.
#
# It is the single largest CDC cost (~900 MB) and batch never uses it, so
# gating it is tempting. Don't, at least not from compose alone: the
# sentinel's health monitor probes Connect unconditionally every 30s
# (sentinel/health_monitor.go:482 → :536) with no "is CDC in use?" gate, so an
# intentionally-absent Connect pins infrastructure:kafka-connect to unhealthy
# forever. The CDC health surface is what the sentinel and the healer read, so
# a permanently-red component there is indistinguishable from a real Connect
# outage — the healer then reasons off a signal that can never clear. Trading
# 900 MB for a health surface that lies is a bad trade on a box this small,
# because a small box is exactly where you need the alerts to mean something.
#
# Gating it safely needs a CDC_ENABLED-style flag (defaulting to today's
# behaviour) that the health monitor honours. Until that exists, Connect stays
# up.