-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
85 lines (81 loc) · 4.01 KB
/
Copy pathdocker-compose.yml
File metadata and controls
85 lines (81 loc) · 4.01 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
# muteki — unified containerized deployment (P2-v3).
#
# One command brings up the whole control plane:
# MUTEKI_HOST_DATA_ROOT=/opt/muteki/data MUTEKI_WEB_PASSWORD=... \
# docker compose up --build
#
# Topology:
# web-api — FastAPI coordinator. Mounts the host docker socket and launches
# WORKER containers as SIBLINGS on the host daemon (not dind). The
# in-container supervisor dials back to web-api:9100 over muteki_net.
# ui — Next command deck; proxies /api → web-api.
# (workers are NOT a compose service — web-api `docker run`s them per-run.)
#
# The four P2-v3 BLOCKERs are addressed by the env + mounts here:
# a) MUTEKI_CONTROL_BIND=0.0.0.0 — receiver reachable by sibling workers.
# b) MUTEKI_WORKER_NETWORK=muteki_net + MUTEKI_CONTROL_HOST=web-api — workers
# join this network and resolve the receiver by the web-api alias.
# c) ${MUTEKI_HOST_DATA_ROOT} bind-mounted at the SAME path in web-api, and
# MUTEKI_SESSIONS_ROOT under it, so worker sibling mounts (resolved by the
# HOST daemon) point at real host paths. _mount_source() is identity here.
# d) MUTEKI_IN_CONTAINER=1 — the swarm hard-fails instead of falling back to a
# host-native local worker.
name: muteki
networks:
muteki_net:
# fixed external-style name → workers join by name; overridable for multiple
# deployments on one host.
name: ${MUTEKI_WORKER_NETWORK:-muteki_net}
services:
web-api:
build:
context: .
dockerfile: docker/web/Dockerfile
image: muteki-web:latest
networks: [muteki_net]
ports:
- "8000:8000" # operator/API; remove to keep it compose-internal
volumes:
# talk to the HOST docker daemon (launch worker sibling containers)
- /var/run/docker.sock:/var/run/docker.sock
# mirror the host data root at the SAME path so worker mounts resolve on host
- ${MUTEKI_HOST_DATA_ROOT:?set MUTEKI_HOST_DATA_ROOT to an absolute host path}:${MUTEKI_HOST_DATA_ROOT}
environment:
MUTEKI_IN_CONTAINER: "1"
MUTEKI_CONTROL_BIND: "0.0.0.0"
MUTEKI_CONTROL_HOST: "web-api"
MUTEKI_WORKER_NETWORK: "${MUTEKI_WORKER_NETWORK:-muteki_net}"
MUTEKI_HOST_DATA_ROOT: "${MUTEKI_HOST_DATA_ROOT}"
# container data root == host root (identity mirror), so _mount_source is a no-op
MUTEKI_CONTAINER_DATA_ROOT: "${MUTEKI_HOST_DATA_ROOT}"
MUTEKI_SESSIONS_ROOT: "${MUTEKI_HOST_DATA_ROOT}/sessions"
MUTEKI_WEB_BIND: "0.0.0.0"
MUTEKI_WEB_PASSWORD: "${MUTEKI_WEB_PASSWORD:?set MUTEKI_WEB_PASSWORD — non-loopback bind requires it}"
MUTEKI_WORKER_IMAGE: "${MUTEKI_WORKER_IMAGE:-ghcr.io/fishcodetech/muteki-worker:latest}"
MUTEKI_WORKER_IMAGE_VERSION: "${MUTEKI_WORKER_IMAGE_VERSION:-}"
# The coordinator brain (planner) + auto-titler use LLMClient, which reads
# the key from the process env. .env is .dockerignore'd (secrets must NOT be
# baked into the image), so it can only reach the container via compose.
# Without it LLMClient sends "Authorization: Bearer " (empty) and httpx
# rejects it ("Illegal header value"). Pass it through from the host .env.
MUTEKI_DEEPSEEK_API_KEY: "${MUTEKI_DEEPSEEK_API_KEY:-}"
MUTEKI_DEEPSEEK_BASE_URL: "${MUTEKI_DEEPSEEK_BASE_URL:-https://api.deepseek.com/v1}"
MUTEKI_LLM_TRUST_ENV: "${MUTEKI_LLM_TRUST_ENV:-0}"
restart: unless-stopped
ui:
build:
context: ./apps/web/ui
dockerfile: ../../../docker/ui/Dockerfile
args:
# Next standalone freezes the rewrites() proxy target at BUILD time, so the
# backend alias must be passed as a build arg (not just a runtime env).
MUTEKI_BACKEND: "http://web-api:8000"
image: muteki-ui:latest
networks: [muteki_net]
ports:
# host port overridable (a dev server may already own 3001); container stays 3001
- "${MUTEKI_UI_PORT:-3001}:3001"
environment:
MUTEKI_BACKEND: "http://web-api:8000" # kept for parity; baked at build (see args)
depends_on: [web-api]
restart: unless-stopped