-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
192 lines (180 loc) · 8.25 KB
/
Copy pathdocker-compose.yml
File metadata and controls
192 lines (180 loc) · 8.25 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
# ── DeepSQL Self-Hosted Stack ─────────────────────────────────────────────────
# Quick start:
# 1. cp .env.example .env
# 2. fill in required values in .env (or run ./scripts/self-host/install.sh)
# 3. docker compose up -d --build
#
# There are no prebuilt DeepSQL images and no container registry: `backend`,
# `frontend`, and `deepsql-agent` are built from this checkout. The first build
# compiles the Java backend and takes several minutes.
#
# Network posture (OSS security): only the frontend (:3000) is published on all
# interfaces by default. Postgres, Valkey, backend, and the Agent API bind to
# loopback on the host (127.0.0.1) so a cloud VM is not WAN-open. Compose-network
# DNS (postgres/valkey/backend/deepsql-agent) is unchanged for inter-service traffic.
#
# Recommended self-host mode — pgvector locally for RAG storage:
# VECTOR_STORE_TYPE=pgvector
# AZURE_SEARCH_ENABLED=false
services:
# ── Vault Database (PostgreSQL + pgvector) ──────────────────────────────────
# pgvector/pgvector image includes the pgvector extension pre-installed.
postgres:
image: pgvector/pgvector:pg18
restart: unless-stopped
environment:
POSTGRES_DB: dba_agent
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_PASSWORD:?Set DB_PASSWORD in .env (install.sh generates one)}
command: >
postgres
-c shared_preload_libraries=pg_stat_statements
-c pg_stat_statements.track=all
-c max_connections=200
ports:
- "127.0.0.1:${DEEPSQL_POSTGRES_PORT:-5432}:5432"
volumes:
- dba-agent-postgres:/var/lib/postgresql
- ./docker/postgres/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d dba_agent"]
interval: 10s
timeout: 5s
retries: 5
# ── Cache (Valkey / Redis-compatible) ────────────────────────────────────────
valkey:
image: valkey/valkey:9.1.1
restart: unless-stopped
environment:
DEEPSQL_VALKEY_PASSWORD: ${DEEPSQL_VALKEY_PASSWORD:?Set DEEPSQL_VALKEY_PASSWORD in .env}
command:
- valkey-server
- --requirepass
- ${DEEPSQL_VALKEY_PASSWORD:?Set DEEPSQL_VALKEY_PASSWORD in .env}
ports:
- "127.0.0.1:${DEEPSQL_VALKEY_PORT:-6379}:6379"
volumes:
- dba-agent-valkey:/data
healthcheck:
test: ["CMD-SHELL", "valkey-cli -a \"$$DEEPSQL_VALKEY_PASSWORD\" ping | grep -q PONG"]
interval: 10s
timeout: 3s
retries: 5
# ── Backend (Spring Boot) ─────────────────────────────────────────────────────
backend:
build:
context: ./backend
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
env_file:
- ${DEEPSQL_RUNTIME_ENV_FILE:-.env}
environment:
# Vault DB — points to the postgres service above
DB_URL: jdbc:postgresql://postgres:5432/dba_agent?sslmode=disable
DB_USERNAME: postgres
DB_PASSWORD: ${DB_PASSWORD:?Set DB_PASSWORD in .env}
# Cache — points to the valkey service above
spring.data.redis.host: valkey
spring.data.redis.port: "6379"
spring.data.redis.password: ${DEEPSQL_VALKEY_PASSWORD:?Set DEEPSQL_VALKEY_PASSWORD in .env}
# Encryption key(s) for the credential vault — required, no baked-in default.
# Set ENCRYPTION_KEYS (and ENCRYPTION_KEY_ID if it holds more than one key) in
# .env; see CLAUDE.md's "Environment Variables" section for the format and a
# generation command.
ENCRYPTION_KEYS: ${ENCRYPTION_KEYS:-}
ENCRYPTION_KEY_ID: ${ENCRYPTION_KEY_ID:-}
# CORS — allow the frontend service (and optional custom domain)
cors.allowed.origins: ${CORS_ALLOWED_ORIGINS:-http://localhost:3000}
# DeepSQL Agent — compose-network URLs (Agent tab, dashboards, Slack/CLI)
AGENT_WEBUI_URL: ${AGENT_WEBUI_URL:-http://deepsql-agent:8787}
AGENT_PROVISIONER_URL: ${AGENT_PROVISIONER_URL:-http://deepsql-agent:8788/provision}
AGENT_PROVISION_SECRET: ${AGENT_PROVISION_SECRET:-}
# Self-host should default to the hardened production profile
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
# Automatically set by install.sh for pgvector self-host mode
SPRING_AUTOCONFIGURE_EXCLUDE: ${SPRING_AUTOCONFIGURE_EXCLUDE:-}
ports:
# Loopback only — public traffic must go through frontend nginx (:3000)
- "127.0.0.1:${DEEPSQL_BACKEND_PORT:-8080}:8080"
volumes:
- dba-agent-logs:/app/logs
healthcheck:
test: ["CMD-SHELL", "curl -fs http://localhost:8080/api/actuator/health || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
# ── DeepSQL Agent (Agent tab, AI dashboards, Slack/CLI agent turns) ───────────
# Fifth container: persona + skills + MCP + profile provisioner. Built from
# agent/Dockerfile. Required for the Agent tab and AI dashboard generation.
# In-container bind remains 0.0.0.0 so backend/frontend can reach it on the
# compose bridge; host publish is loopback-only (nginx /agent-api is the
# public path and is gated with auth_request).
deepsql-agent:
build:
context: .
dockerfile: agent/Dockerfile
restart: unless-stopped
depends_on:
backend:
condition: service_healthy
env_file:
- ${DEEPSQL_RUNTIME_ENV_FILE:-.env}
environment:
# LLM — same BYO credentials the backend uses
DEEPSQL_CHAT_PROVIDER: ${DEEPSQL_CHAT_PROVIDER:-openai}
DEEPSQL_CHAT_API_KEY: ${DEEPSQL_CHAT_API_KEY:-}
DEEPSQL_CHAT_ENDPOINT: ${DEEPSQL_CHAT_ENDPOINT:-}
DEEPSQL_CHAT_MODEL: ${DEEPSQL_CHAT_MODEL:-gpt-5.4}
# Reach the backend over the compose network (MCP tools + provisioner).
# Override to http://host.docker.internal:8080/api/ when the Java backend
# runs on the host (native `mvn spring-boot:run`) instead of Compose.
DEEPSQL_API_BASE_URL: ${DEEPSQL_API_BASE_URL:-http://backend:8080/api/}
# Shared secret with backend AgentBridgeService
AGENT_PROVISION_SECRET: ${AGENT_PROVISION_SECRET:-}
# Origins allowed by the agent API CSRF check
DEEPSQL_AGENT_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-http://localhost:3000},http://frontend
DEEPSQL_AGENT_TRUSTED_AUTH_HEADER: X-Remote-User
# Frontend nginx + backend share the compose bridge; without this the
# agent ignores X-Remote-User (peer is not loopback) and every Agent
# tab / dashboard call returns 401 Authentication required.
DEEPSQL_AGENT_TRUSTED_PROXY_CIDRS: ${DEEPSQL_AGENT_TRUSTED_PROXY_CIDRS:-10.0.0.0/8,172.16.0.0/12,192.168.0.0/16}
HERMES_WEBUI_TRUSTED_PROXY_CIDRS: ${DEEPSQL_AGENT_TRUSTED_PROXY_CIDRS:-10.0.0.0/8,172.16.0.0/12,192.168.0.0/16}
HERMES_WEBUI_TRUSTED_AUTH_HEADER: X-Remote-User
extra_hosts:
- "host.docker.internal:host-gateway"
ports:
- "127.0.0.1:${DEEPSQL_AGENT_PORT:-8787}:8787"
- "127.0.0.1:${DEEPSQL_AGENT_PROVISIONER_PORT:-8788}:8788"
volumes:
- dba-agent-agent:/var/lib/deepsql-agent
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8788/health || exit 1"]
interval: 30s
timeout: 5s
retries: 5
start_period: 90s
# ── Frontend (React + nginx) ──────────────────────────────────────────────────
frontend:
build:
context: .
# VITE_API_URL is deliberately left unset: the nginx config in this image
# proxies /api to the backend service, so the bundle uses a relative path.
# Set it only if you serve the frontend from a different origin.
restart: unless-stopped
depends_on:
backend:
condition: service_healthy
deepsql-agent:
condition: service_started
ports:
- "${DEEPSQL_FRONTEND_PORT:-3000}:80"
volumes:
dba-agent-postgres:
dba-agent-valkey:
dba-agent-logs:
dba-agent-agent: