-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
221 lines (207 loc) · 5.93 KB
/
docker-compose.yml
File metadata and controls
221 lines (207 loc) · 5.93 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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# docker-compose.yml — Sentinel local development stack
# Brings up Postgres+pgvector, Dragonfly, NATS, n8n, MinIO, and all Sentinel services.
# Usage:
# docker compose up -d # start everything
# docker compose logs -f api # follow one service
# docker compose down -v # tear down and wipe volumes
name: sentinel
x-common-env: &common-env
NODE_ENV: ${NODE_ENV:-development}
LOG_LEVEL: ${LOG_LEVEL:-info}
DATABASE_URL: postgres://sentinel:sentinel@postgres:5432/sentinel
REDIS_URL: redis://dragonfly:6379/0
NATS_URL: nats://nats:4222
S3_ENDPOINT: http://minio:9000
S3_ACCESS_KEY: ${S3_ACCESS_KEY:-sentinel}
S3_SECRET_KEY: ${S3_SECRET_KEY:-sentinel-secret}
S3_BUCKET: ${S3_BUCKET:-sentinel-artifacts}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
ANTHROPIC_MODEL: ${ANTHROPIC_MODEL:-claude-opus-4-7}
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
services:
# ---- Data plane -----------------------------------------------------------
postgres:
image: pgvector/pgvector:pg17
restart: unless-stopped
environment:
POSTGRES_USER: sentinel
POSTGRES_PASSWORD: sentinel
POSTGRES_DB: sentinel
volumes:
- postgres-data:/var/lib/postgresql/data
- ./infra/docker/postgres-init.sql:/docker-entrypoint-initdb.d/00-init.sql:ro
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sentinel -d sentinel"]
interval: 5s
timeout: 3s
retries: 10
dragonfly:
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
restart: unless-stopped
command: ["--logtostderr", "--proactor_threads=2"]
ulimits:
memlock: -1
volumes:
- dragonfly-data:/data
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
nats:
image: nats:2.10-alpine
restart: unless-stopped
command: ["-js", "-m", "8222", "-sd", "/data"]
volumes:
- nats-data:/data
ports:
- "4222:4222"
- "8222:8222"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8222/healthz"]
interval: 5s
timeout: 3s
retries: 10
minio:
image: minio/minio:latest
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${S3_ACCESS_KEY:-sentinel}
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:-sentinel-secret}
volumes:
- minio-data:/data
ports:
- "9000:9000"
- "9001:9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 5s
timeout: 3s
retries: 10
minio-init:
image: minio/mc:latest
depends_on:
minio:
condition: service_healthy
entrypoint: >
/bin/sh -c "
mc alias set local http://minio:9000 ${S3_ACCESS_KEY:-sentinel} ${S3_SECRET_KEY:-sentinel-secret};
mc mb -p local/${S3_BUCKET:-sentinel-artifacts} || true;
mc anonymous set download local/${S3_BUCKET:-sentinel-artifacts} || true;
exit 0;
"
# ---- Automation -----------------------------------------------------------
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
environment:
N8N_HOST: 0.0.0.0
N8N_PORT: 5678
N8N_PROTOCOL: http
NODE_ENV: production
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: sentinel
DB_POSTGRESDB_PASSWORD: sentinel
N8N_DIAGNOSTICS_ENABLED: "false"
N8N_PERSONALIZATION_ENABLED: "false"
volumes:
- n8n-data:/home/node/.n8n
- ./infra/n8n/workflows:/workflows:ro
ports:
# Map host 5679 since another n8n instance often already binds 5678.
- "5679:5678"
depends_on:
postgres:
condition: service_healthy
# ---- Sentinel services ----------------------------------------------------
api:
build:
context: .
dockerfile: infra/docker/api.Dockerfile
restart: unless-stopped
environment:
<<: *common-env
API_HOST: 0.0.0.0
API_PORT: 4000
API_JWT_SECRET: ${API_JWT_SECRET:-dev-secret-change-me-in-prod-1234567890}
N8N_URL: http://n8n:5678
SCANNER_URL: http://scanner:4100
ANALYZER_URL: http://analyzer:4200
ports:
- "4000:4000"
depends_on:
postgres:
condition: service_healthy
dragonfly:
condition: service_healthy
nats:
condition: service_healthy
scanner:
build:
context: .
dockerfile: infra/docker/scanner.Dockerfile
restart: unless-stopped
environment:
<<: *common-env
SCANNER_HOST: 0.0.0.0
SCANNER_PORT: 4100
ports:
- "4100:4100"
volumes:
- scanner-work:/tmp/sentinel-scans
depends_on:
nats:
condition: service_healthy
analyzer:
build:
context: .
dockerfile: infra/docker/analyzer.Dockerfile
restart: unless-stopped
environment:
<<: *common-env
ANALYZER_HOST: 0.0.0.0
ANALYZER_PORT: 4200
ports:
- "4200:4200"
depends_on:
postgres:
condition: service_healthy
nats:
condition: service_healthy
web:
build:
context: .
dockerfile: infra/docker/web.Dockerfile
args:
PUBLIC_API_URL: http://localhost:4000
PUBLIC_WS_URL: ws://localhost:4000/ws
restart: unless-stopped
ports:
- "5173:3000"
depends_on:
- api
# ---- Observability --------------------------------------------------------
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
restart: unless-stopped
command: ["--config=/etc/otel-collector.yaml"]
volumes:
- ./infra/docker/otel-collector.yaml:/etc/otel-collector.yaml:ro
ports:
- "4317:4317"
- "4318:4318"
volumes:
postgres-data:
dragonfly-data:
nats-data:
minio-data:
n8n-data:
scanner-work: