Files
LedgerLine/docker-compose.yml
T
Movses AslanyanandClaude Opus 5.5 f721df3063 Auto-instrument sanctions with OpenTelemetry zero-code
Add opentelemetry-distro/exporter-otlp (pinned pair) and run
opentelemetry-bootstrap at build time; wrap the sanctions command with
opentelemetry-instrument and configure the SDK via OTEL_* env (traces
only, OTLP/HTTP to otlp.vione.cloud). create-secrets.sh now writes the
base64 OTLP auth header into .env.observability.

The G10 guard test (no observability libraries in requirements) is
expected to fail from here until the guard suite is retired in Phase 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 20:09:38 +03:30

215 lines
5.6 KiB
YAML

x-app-env: &app-env
POSTGRES_DSN: postgresql+asyncpg://ledgerline:ledgerline@postgres:5432/ledgerline
REDIS_URL: redis://redis:6379/0
GATEWAY_URL: http://gateway:8000
LEDGER_URL: http://ledger:8001
FRAUD_URL: http://fraud:8002
SANCTIONS_URL: http://sanctions:8003
INSIGHTS_URL: http://insights:8004
NOTIFIER_URL: http://notifier:8005
x-app-build: &app-build
build:
context: .
dockerfile: Dockerfile
x-app-volumes: &app-volumes
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
x-app-depends: &app-depends
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
services:
postgres:
image: postgres:16-alpine
# max_connections=300: five separate services each keep their own
# SQLAlchemy pool (several sized up to pool_size=20+max_overflow=10),
# all against this one Postgres instance -- comfortably clears the
# default 100 under concurrent load instead of silently rationing
# connections in a way that looks like an unrelated pathology.
command:
- postgres
- -c
- shared_preload_libraries=pg_stat_statements
- -c
- pg_stat_statements.track=all
- -c
- pg_stat_statements.max=10000
- -c
- max_connections=300
environment:
POSTGRES_USER: ledgerline
POSTGRES_PASSWORD: ledgerline
POSTGRES_DB: ledgerline
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ledgerline -d ledgerline"]
interval: 3s
timeout: 3s
retries: 20
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 3s
timeout: 3s
retries: 20
gateway:
<<: [*app-build, *app-depends]
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
environment:
<<: *app-env
SERVICE_NAME: gateway
command: uvicorn services.gateway.app:app --host 0.0.0.0 --port 8000 --reload --no-access-log
ports:
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/healthz"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
ledger:
<<: [*app-build, *app-depends]
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
environment:
<<: *app-env
SERVICE_NAME: ledger
command: uvicorn services.ledger.app:app --host 0.0.0.0 --port 8001 --reload --no-access-log
ports:
- "8001:8001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8001/healthz"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
fraud:
<<: [*app-build, *app-depends]
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
environment:
<<: *app-env
SERVICE_NAME: fraud
command: uvicorn services.fraud.app:app --host 0.0.0.0 --port 8002 --reload --no-access-log
ports:
- "8002:8002"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8002/healthz"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
sanctions:
<<: [*app-build, *app-depends]
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
environment:
<<: *app-env
SERVICE_NAME: sanctions
OTEL_SERVICE_NAME: sanctions
OTEL_RESOURCE_ATTRIBUTES: deployment.environment.name=prod
OTEL_EXPORTER_OTLP_ENDPOINT: https://otlp.vione.cloud
OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
OTEL_TRACES_EXPORTER: otlp
OTEL_METRICS_EXPORTER: none
OTEL_LOGS_EXPORTER: none
env_file:
- .env.observability
command: opentelemetry-instrument uvicorn services.sanctions.app:app --host 0.0.0.0 --port 8003 --reload --no-access-log
ports:
- "8003:8003"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8003/healthz"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
insights:
<<: [*app-build, *app-depends]
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
environment:
<<: *app-env
SERVICE_NAME: insights
command: uvicorn services.insights.app:app --host 0.0.0.0 --port 8004 --reload --no-access-log
ports:
- "8004:8004"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8004/healthz"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
notifier:
<<: [*app-build, *app-depends]
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
environment:
<<: *app-env
SERVICE_NAME: notifier
command: uvicorn services.notifier.app:app --host 0.0.0.0 --port 8005 --reload --no-access-log
ports:
- "8005:8005"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8005/healthz"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
audit:
<<: [*app-build, *app-depends]
volumes:
- ./common:/app/common
- ./services:/app/services
- ./db:/app/db
- ./scripts:/app/scripts
environment:
<<: *app-env
SERVICE_NAME: audit
command: python -m services.audit.worker
volumes:
pgdata: