forked from DreamLab-AI/VisionClaw
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
222 lines (213 loc) · 9.53 KB
/
Copy pathdocker-compose.yml
File metadata and controls
222 lines (213 loc) · 9.53 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
222
# AUTO-GENERATED from agentbox.toml via flake.nix — do not edit by hand.
# Run: nix build .#compose
services:
# R-025: optional `claude-zai` sidecar. management-api/utils/process-manager.js
# dials http://claude-zai-service:9600 when the Z.AI/GLM provider is selected.
# No service is emitted here by default — the sidecar is operator-provided and
# joins visionclaw_network as `claude-zai-service`. process-manager guards the
# URL so its absence is a no-op when Z.AI is not in use (handled separately).
ruvector-postgres:
image: ruvnet/ruvector-postgres:2.0.5@sha256:7fb09d439d82fccbe6e0035d09f91c9dce456bb2d70cb2e8d6afb12a6afa2051
container_name: ruvector-postgres
restart: unless-stopped
environment:
- POSTGRES_DB=ruvector
- POSTGRES_USER=ruvector
- POSTGRES_PASSWORD=${RUVECTOR_PG_PASSWORD:?set RUVECTOR_PG_PASSWORD}
volumes:
- ruvector-pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ruvector -d ruvector"]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
networks:
- default
- visionclaw
agentbox:
image: ${AGENTBOX_IMAGE_REF:-agentbox:runtime-x86_64-linux}
container_name: agentbox
hostname: agentbox
restart: unless-stopped
depends_on:
ruvector-postgres:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9090/ready"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
# R-003: host exposure is loopback-only (SSH-tunnel model) — reached via
# tunnel; sibling-container access on the docker network is gated by
# per-service auth, not by host port binding.
# Exception (ADR-045 D2): 9096 is the NIP-98 sovereign ingress — the ONE
# identity-gated LAN door to the interaction plane (and, via its routing
# table, /mgmt/ → management-api). 9095 (aoe serve) is NEVER published:
# it binds container-loopback with --auth none behind this proxy (N-05).
ports:
- "9096:9096"
- "127.0.0.1:9090:9090"
- "127.0.0.1:9700:9700"
- "127.0.0.1:9091:9091"
- "127.0.0.1:8484:8484"
- "127.0.0.1:8888:8888"
- "127.0.0.1:5901:5901"
- "127.0.0.1:8080:8080"
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- GITHUB_TOKEN=${GITHUB_TOKEN:-}
- OPENAI_API_KEY=${OPENAI_API_KEY:-ollama}
- OPENAI_BASE_URL=${OPENAI_BASE_URL:-http://ollama:11434/v1}
- OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-http://ollama:11434}
- OLLAMA_MODEL=${OLLAMA_MODEL:-gemma-4-31B-it-qat}
# The Loom facade, as one name the whole container agrees on. The image
# bakes no estate address (this repository is public), so the value has
# to arrive here: LOOM_BASE_URL from .env if the operator sets it, else
# derived from LOOM_FACADE_URL, else the in-network loom sidecar. The
# /v1 lives inside the default so a LOOM_BASE_URL that already carries
# one is not given a second.
- LOOM_BASE_URL=${LOOM_BASE_URL:-${LOOM_FACADE_URL:-http://loom:8080}/v1}
# The dream engine's ssh target for the annexe host. Referenced by
# [dream_machine].hp_host; empty is fine and means "no annexe", which
# the engine reports rather than shelling out to nowhere.
- CONNECTED_NODE_SSH=${CONNECTED_NODE_SSH:-}
- GEMMA_BASE_URL=${GEMMA_BASE_URL:-${LOOM_BASE_URL:-${LOOM_FACADE_URL:-http://loom:8080}/v1}}
# Ontology condensation posts to {endpoint}/chat/completions, so this is
# a /v1 base. Empty is a working state: the server reports the missing
# variable and stops, rather than fetching a hostname that cannot resolve.
- ONTOLOGY_CONDENSE_ENDPOINT=${ONTOLOGY_CONDENSE_ENDPOINT:-${LOOM_BASE_URL:-${LOOM_FACADE_URL:-http://loom:8080}/v1}}
- GEMMA_MODEL=${GEMMA_MODEL:-gemma-4-31B-it-qat}
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}
- DEEPSEEK_BASE_URL=${DEEPSEEK_BASE_URL:-https://api.deepseek.com/v1}
- GOOGLE_API_KEY=${GOOGLE_API_KEY:-}
- GOOGLE_GEMINI_API_KEY=${GOOGLE_GEMINI_API_KEY:-}
- GEMINI_API_KEY=${GEMINI_API_KEY:-}
- MANAGEMENT_API_KEY=${MANAGEMENT_API_KEY:-}
- MANAGEMENT_API_AUTH_MODE=${MANAGEMENT_API_AUTH_MODE:-hybrid}
# Shared service key for VisionClaw mutating endpoints (broker write-back);
# must match VISIONCLAW_AGENT_KEY on the VisionClaw container.
- VISIONCLAW_AGENT_KEY=${VISIONCLAW_AGENT_KEY:-}
- NOSTR_RELAYS=${NOSTR_RELAYS:-wss://relay.damus.io,wss://relay.primal.net}
- AGENTBOX_AGENT_ID=${AGENTBOX_AGENT_ID:-agentbox-core}
- AGENTBOX_IMAGE_HASH=${AGENTBOX_IMAGE_HASH:-}
- AGENTBOX_MANIFEST_CHECKSUM=${AGENTBOX_MANIFEST_CHECKSUM:-}
- AGENTBOX_METRICS_PORT=9091
- AGENTBOX_OTLP_ENDPOINT=
- AGENTBOX_LOG_LEVEL=info
- XINFERENCE_ENDPOINT=${XINFERENCE_ENDPOINT:-http://xinference:9997}
- EMBEDDING_MODEL=${EMBEDDING_MODEL:-bge-small-en-v1.5}
# Baseline: supervisord runs as PID 1 root, with per-program `user=devuser`
# drops on every long-running service. Root is required at boot for
# tmpfs subdir creation, cert generation, and chowning runtime dirs to
# uid 1000. R-005/SEC-001: no runtime sudo — root-at-boot via supervisord
# (PID 1) is the only elevation.
# SETUID/SETGID are REQUIRED: supervisord calls setgroups()/setuid() to
# demote children to devuser, and that needs CAP_SETGID/CAP_SETUID even
# for privilege *dropping*. no-new-privileges:true neuters setuid file
# bits at execve (privilege *gaining*) but does not replace these caps.
# Per ADR-007 §4a hardening posture; see PRD-003 §5.4 and ADR-027 §amendment.
read_only: true
cap_drop:
- ALL
cap_add:
- CHOWN
- FOWNER
- DAC_OVERRIDE
- AUDIT_WRITE
- KILL
- NET_ADMIN
- SETUID
- SETGID
tmpfs:
# Sizes follow [resources.tmpfs] in agentbox.toml (ADR-2034): the committed
# file had drifted to 1G/64M/1G/256M while the flake emitted 2G/256M/4G/1G,
# and the live ~/.npm (256M) sat at 100 % -> npx ENOSPC on 2026-09-05.
- /tmp:mode=1777,size=2G
- /run:mode=755,size=256M,uid=1000,gid=1000
- /var/run:mode=755,size=16M,uid=1000,gid=1000
- /var/log:mode=755,size=128M,uid=1000,gid=1000
- /var/log/supervisor:mode=755,size=64M,uid=1000,gid=1000
- /var/lib/https-bridge:mode=755,size=8M,uid=1000,gid=1000
# General ephemeral XDG cache. The ~2.8G privacy model has its own
# persistent child volume at .cache/huggingface below.
- /home/devuser/.cache:mode=755,size=4G,uid=1000,gid=1000
# Legacy native npm installers (notably sharp) still hard-code ~/.npm
# even when NPM_CONFIG_CACHE points at the writable workspace.
- /home/devuser/.npm:mode=755,size=1G,uid=1000,gid=1000
- /home/devuser/.local:mode=755,size=128M,uid=1000,gid=1000
- /home/devuser/.config:mode=755,size=64M,uid=1000,gid=1000
- /home/devuser/.claude-flow:mode=755,size=64M,uid=1000,gid=1000
- /home/devuser/.codex:mode=755,size=512M,uid=1000,gid=1000
- /home/devuser/.antigravity:mode=755,size=256M,uid=1000,gid=1000
- /home/devuser/.gemini:mode=755,size=256M,uid=1000,gid=1000
- /var/cache:mode=755,size=512M,uid=1000,gid=1000
- /usr/local/bin:mode=755,size=8M,exec,suid
- /app/mcp-logs:mode=755,size=100M,uid=1000,gid=1000
- /tmp/.X11-unix:mode=1777
- /run/user/1000:mode=700,uid=1000,gid=1000
security_opt:
- no-new-privileges:true
- seccomp=./config/seccomp-agentbox.json
volumes:
- ./agentbox.toml:/etc/agentbox.toml:ro
- ./workspace:/home/devuser/workspace
- ./projects:/projects
- ruvector-data:/var/lib/ruvector
- solid-data:/var/lib/solid
- sovereign-identities:/var/lib/agentbox/identities
- agentbox-secrets:/var/lib/agentbox/secrets
- code-harness-data:/var/lib/agentbox/code-harness
- agentbox-events:/var/lib/agentbox/events
- hf-cache:/home/devuser/.cache/huggingface
- codeserver-config:/home/devuser/.local/share/code-server
# OpenCode's session store. ~/.local is a 128 MB tmpfs shared with every
# XDG-aware CLI; a day of agent runs filled it and the next session died on a
# database checkpoint reporting a full disk (2026-09-11). Layered like
# code-server's: the tmpfs mounts first, this volume on top.
- opencode-store:/home/devuser/.local/share/opencode
- aoe-profiles:/home/devuser/.config/agent-of-empires/profiles
- consultations-data:/var/lib/agentbox/consultations
- telemetry-data:/var/lib/agentbox/telemetry
- nostr-relay-data:/var/lib/nostr-relay
- tailscale-state:/var/lib/tailscale
networks:
- default
- visionclaw
volumes:
ruvector-pg-data:
name: ruvector_postgres_data_v2
ruvector-data:
name: agentbox-ruvector-data
solid-data:
name: agentbox-solid-data
sovereign-identities:
name: agentbox-sovereign-identities
agentbox-secrets:
name: agentbox-secrets
code-harness-data:
name: agentbox-code-harness-data
agentbox-events:
name: agentbox-events
hf-cache:
name: agentbox-hf-cache
codeserver-config:
name: agentbox-codeserver-config
opencode-store:
name: agentbox-opencode-store
aoe-profiles:
name: agentbox-aoe-profiles
consultations-data:
name: agentbox-consultations-data
telemetry-data:
name: agentbox-telemetry-data
nostr-relay-data:
name: agentbox-nostr-relay-data
tailscale-state:
name: agentbox-tailscale-state
networks:
default:
visionclaw:
name: visionclaw_network
external: true