-
Notifications
You must be signed in to change notification settings - Fork 159
Expand file tree
/
Copy pathdocker-compose.yaml
More file actions
138 lines (133 loc) · 4.92 KB
/
docker-compose.yaml
File metadata and controls
138 lines (133 loc) · 4.92 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
# Phantom AI Agent - Full Stack
# Usage: docker compose up -d
# Docs: https://github.com/ghostwright/phantom
services:
# =========================================================================
# Phantom: The AI agent
# =========================================================================
phantom:
build:
context: .
dockerfile: Dockerfile
container_name: phantom
ports:
- "${PORT:-3100}:3100"
env_file:
- .env
environment:
# Override memory URLs to use Docker service names
- QDRANT_URL=http://qdrant:6333
- OLLAMA_URL=http://ollama:11434
# Bias the host OOM killer toward qdrant/ollama under memory pressure so
# the main phantom process stays alive and can log the squeeze before it
# is killed last.
oom_score_adj: -500
# Give phantom twice the default CPU share under cgroup contention so
# the reflection subprocess and the live agent do not starve when
# qdrant/ollama are also busy. No cpu.max quota is set because the
# current no-throttle behavior is correct.
cpu_shares: 2048
# Non-root: Claude Code CLI refuses --dangerously-skip-permissions as root.
# Docker socket access is granted via group_add with the host's docker GID.
# Override DOCKER_GID in .env if your host's docker group has a different ID
# (find it with: stat -c '%g' /var/run/docker.sock).
group_add:
- "${DOCKER_GID:-988}"
# Explicit DNS: hosts using systemd-resolved expose 127.0.0.53 which is
# unreachable from bridge-network containers. Cloudflare + Google as fallback.
dns:
- 1.1.1.1
- 8.8.8.8
volumes:
# Persistent state - survives docker compose down/up
- phantom_config:/app/config
- phantom_evolved:/app/phantom-config
- phantom_data:/app/data
- phantom_public:/app/public
- phantom_repos:/app/repos
# Claude Code credentials (persists `claude login` across restarts so
# subscription users do not have to re-authenticate on every upgrade)
- phantom_claude:/home/phantom/.claude
# Docker socket for sibling container creation
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
qdrant:
condition: service_started
ollama:
condition: service_started
restart: unless-stopped
deploy:
resources:
limits:
# 8 GiB sizes for peak Phase 3 reflection concurrency: the main
# phantom process plus an active agent query subprocess plus one
# reflection subprocess running at Haiku, Sonnet, or Opus tier.
# Qdrant and Ollama get their own caps below. The prior 2 GiB cap
# cgroup-OOM-killed evolution subprocesses under load.
memory: 8G
# Cap the total number of processes this service can create. A
# runaway evolution subprocess spawn loop is bounded here in
# addition to the Phase 0 application-layer mutex and the Phase 2
# cadence. Compose v5+ requires pids to live under
# deploy.resources.limits alongside memory; using both top-level
# pids_limit and this block errors with "distinct values".
pids: 256
reservations:
memory: 512M
networks:
- phantom-net
# =========================================================================
# Qdrant: Vector database for memory (episodic, semantic, procedural)
# =========================================================================
qdrant:
image: qdrant/qdrant:latest
container_name: phantom-qdrant
volumes:
- qdrant_data:/qdrant/storage
environment:
- QDRANT__SERVICE__GRPC_PORT=6334
# No healthcheck: the qdrant/qdrant image has no curl/wget.
# The phantom entrypoint polls /healthz with its own retry loop.
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G
reservations:
memory: 512M
networks:
- phantom-net
# =========================================================================
# Ollama: Local embedding model (nomic-embed-text)
# =========================================================================
ollama:
image: ollama/ollama:latest
container_name: phantom-ollama
volumes:
- ollama_data:/root/.ollama
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G
reservations:
memory: 1G
networks:
- phantom-net
# =========================================================================
# Named volumes - persist across container restarts and redeployments
# Use 'docker compose down' to stop (keeps data)
# Use 'docker compose down -v' to destroy all data (clean slate)
# =========================================================================
volumes:
phantom_config:
phantom_evolved:
phantom_data:
phantom_public:
phantom_repos:
phantom_claude:
qdrant_data:
ollama_data:
networks:
phantom-net:
driver: bridge