-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
181 lines (174 loc) · 6.02 KB
/
Copy pathdocker-compose.yml
File metadata and controls
181 lines (174 loc) · 6.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# --- L9_META ---
# l9_schema: 1
# origin: l9-template
# engine: graph
# layer: [docker]
# tags: [L9_TEMPLATE, docker, dev]
# owner: platform
# status: active
# --- /L9_META ---
#
# L9 Graph Cognitive Engine — Local Dev Docker Compose
# Usage: docker compose up -d
# API: http://localhost:8000/v1/health
# Neo4j: http://localhost:7474 (browser), bolt://localhost:7687
# Redis: localhost:6379
# Postgres: localhost:5432 (PacketStore + ComplianceEngine audit-flush pool)
services:
# ── API Server ───────────────────────────────────────────
api:
build:
context: .
dockerfile: Dockerfile
container_name: l9-graph-api
ports:
- "8000:8000"
environment:
# Engine lifecycle hook — wires Graph engine to chassis
L9_LIFECYCLE_HOOK: engine.boot:GraphLifecycle
# Chassis selection (chassis.entrypoint:create_app)
L9_CHASSIS: legacy
# SDK chassis config — inert while L9_CHASSIS=legacy. NodeRuntimeConfig
# is frozen with extra="forbid", so names must match the SDK exactly.
L9_ENVIRONMENT: local
L9_SERVICE_NAME: graph-engine
L9_SERVICE_VERSION: 1.1.0
HOST: 0.0.0.0
L9_ENFORCE_GATE_ONLY_INGRESS: "true"
L9_GATE_NODE_NAME: gate
L9_REQUIRE_SIGNATURE: "true"
L9_SIGNING_ALGORITHM: hmac-sha256
L9_SIGNING_KEY: dev-shared-hmac-secret-not-for-production
L9_SIGNING_KEY_ID: graph-engine-v1
L9_ALLOWED_ACTIONS: match,sync,admin,outcomes,resolve,health,healthcheck,enrich
L9_MAX_ATTACHMENTS: "0"
# Required: SDK defaults (10MB attachment vs 256KB packet) are mutually invalid.
L9_MAX_ATTACHMENT_SIZE_BYTES: "0"
# Neo4j — uses Docker service name, not localhost
NEO4J_URI: bolt://neo4j:7687
NEO4J_USERNAME: neo4j
NEO4J_PASSWORD: l9-dev-password
NEO4J_POOL_SIZE: "20"
# Redis
REDIS_URL: redis://redis:6379/0
# API
API_KEY: dev-key-sha256-not-for-production
LOG_LEVEL: debug
CORS_ORIGINS: '["http://localhost:3000","http://localhost:8000"]'
# Scoring defaults
W_STRUCTURAL: "0.30"
W_GEO: "0.25"
W_REINFORCEMENT: "0.20"
W_FRESHNESS: "0.10"
GEO_DECAY_KM: "800.0"
COMMUNITY_CROSS_BIAS: "0.92"
MAX_RESULTS: "25"
# Domain
DOMAINS_ROOT: domains
# Postgres — ComplianceEngine audit-flush pool (soft dependency; None
# disables flush with a warning, does not block startup — see
# engine/boot.py). Same instance also backs PacketStore below.
POSTGRES_DSN: postgresql://l9_engine:l9-dev-password@postgres:5432/l9_graph
# PacketStore — dual-gated with settings.outcome_persistence_enabled
PACKET_STORE_ENABLED: "true"
PACKET_STORE_DSN: postgresql://l9_engine:l9-dev-password@postgres:5432/l9_graph
volumes:
# Hot-reload: mount source code so changes reflect without rebuild
- ./engine:/app/engine:ro
- ./domains:/app/domains:ro
depends_on:
neo4j:
condition: service_healthy
redis:
condition: service_healthy
postgres:
condition: service_healthy
healthcheck:
test: ["CMD", "python", "-c", "import httpx; r=httpx.get('http://localhost:8000/v1/health'); exit(0 if r.status_code==200 and r.json().get('ready', True) else 1)"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
restart: unless-stopped
networks:
- l9-graph
# ── Neo4j 5.x Enterprise + GDS ──────────────────────────
neo4j:
image: neo4j:5-enterprise
container_name: l9-graph-neo4j
ports:
- "7475:7474" # Browser (7475 external -> 7474 internal)
- "7688:7687" # Bolt (7688 external -> 7687 internal)
environment:
NEO4J_AUTH: neo4j/l9-dev-password
NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
NEO4J_PLUGINS: '["apoc", "graph-data-science"]'
NEO4J_dbms_memory_heap_initial__size: 512m
NEO4J_dbms_memory_heap_max__size: 1g
NEO4J_dbms_memory_pagecache_size: 512m
NEO4J_dbms_security_procedures_unrestricted: apoc.*,gds.*
NEO4J_dbms_security_procedures_allowlist: apoc.*,gds.*
volumes:
- neo4j_data:/data
- neo4j_logs:/logs
- neo4j_plugins:/plugins
healthcheck:
test: ["CMD-SHELL", "cypher-shell -u neo4j -p l9-dev-password 'RETURN 1' || exit 1"]
interval: 10s
timeout: 10s
retries: 10
start_period: 30s
restart: unless-stopped
networks:
- l9-graph
# ── Redis 7.x ───────────────────────────────────────────
redis:
image: redis:7-alpine
container_name: l9-graph-redis
ports:
- "6379:6379"
command: redis-server --maxmemory 128mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
restart: unless-stopped
networks:
- l9-graph
# ── PostgreSQL 16 (PacketStore + ComplianceEngine audit) ──
postgres:
image: postgres:16-alpine
container_name: l9-graph-postgres
ports:
- "5432:5432"
environment:
POSTGRES_USER: l9_engine
POSTGRES_PASSWORD: l9-dev-password
POSTGRES_DB: l9_graph
volumes:
- postgres_data:/var/lib/postgresql/data
# Auto-applied on first container init only (postgres entrypoint
# convention) — schema for packet_store, lineage_graph, hop_trace,
# delegation_chain, packet_audit_log tables.
- ./engine/packet/packet_store.sql:/docker-entrypoint-initdb.d/01_packet_store.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U l9_engine -d l9_graph"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
restart: unless-stopped
networks:
- l9-graph
volumes:
neo4j_data:
neo4j_logs:
neo4j_plugins:
redis_data:
postgres_data:
networks:
l9-graph:
driver: bridge