-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
117 lines (114 loc) · 5.61 KB
/
docker-compose.yml
File metadata and controls
117 lines (114 loc) · 5.61 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
services:
# ── Backend: FastAPI + uvicorn ──────────────────────────────────
backend:
build:
context: .. # repo 根目录(包含 Cargo.toml + skilllite/ + crates/)
dockerfile: evotown/Dockerfile.backend
restart: unless-stopped
# ── 生产资源限制(防止单容器耗尽宿主机资源)──────────────────────
deploy:
resources:
limits:
cpus: "${BACKEND_CPU_LIMIT:-2.0}"
memory: "${BACKEND_MEM_LIMIT:-4G}"
reservations:
cpus: "0.5"
memory: 512M
environment:
# LLM API 密钥 — 支持两种命名:OPENAI_API_KEY 或 API_KEY(skilllite 本地 .env 惯例)
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
- OPENAI_BASE_URL=${OPENAI_BASE_URL:-}
- API_KEY=${API_KEY:-}
- BASE_URL=${BASE_URL:-}
- MODEL=${MODEL:-}
# skilllite 运行时参数(从 .env 透传)
- SKILLLITE_MAX_TOKENS=${SKILLLITE_MAX_TOKENS:-8192}
- SKILLLITE_ENABLE_MEMORY_VECTOR=${SKILLLITE_ENABLE_MEMORY_VECTOR:-}
- SKILLLITE_LONG_TEXT_STRATEGY=${SKILLLITE_LONG_TEXT_STRATEGY:-}
- SKILLLITE_MAP_MODEL=${SKILLLITE_MAP_MODEL:-}
- SKILLLITE_QUIET=${SKILLLITE_QUIET:-}
# 若宿主机不支持 user namespace(bwrap Permission denied),设为 1 跳过沙箱
- SKILLLITE_NO_SANDBOX=${SKILLLITE_NO_SANDBOX:-}
- SKILLBOX_AUTO_APPROVE=${SKILLBOX_AUTO_APPROVE:-0}
- SKILLBOX_ALLOW_PLAYWRIGHT=${SKILLBOX_ALLOW_PLAYWRIGHT:-}
- SKILLBOX_USE_IPC=${SKILLBOX_USE_IPC:-}
# 分通道 provider(DISPATCHER/SOCIAL/JUDGE/CHRONICLE 各自独立 endpoint)
# 格式:{CHANNEL}_BASE_URL / {CHANNEL}_API_KEY / {CHANNEL}_MODEL
# 未配置时自动 fallback → LOCAL_BASE_URL → 主 BASE_URL
- DISPATCHER_BASE_URL=${DISPATCHER_BASE_URL:-}
- DISPATCHER_API_KEY=${DISPATCHER_API_KEY:-}
- DISPATCHER_MODEL=${DISPATCHER_MODEL:-}
- SOCIAL_BASE_URL=${SOCIAL_BASE_URL:-}
- SOCIAL_API_KEY=${SOCIAL_API_KEY:-}
- SOCIAL_MODEL=${SOCIAL_MODEL:-}
- JUDGE_BASE_URL=${JUDGE_BASE_URL:-}
- JUDGE_API_KEY=${JUDGE_API_KEY:-}
- JUDGE_MODEL=${JUDGE_MODEL:-}
- CHRONICLE_BASE_URL=${CHRONICLE_BASE_URL:-}
- CHRONICLE_API_KEY=${CHRONICLE_API_KEY:-}
- CHRONICLE_MODEL=${CHRONICLE_MODEL:-}
# 本地模型(Ollama)路由 — 向后兼容,无通道专属 endpoint 时生效
# 注意:Docker 内访问宿主机 Ollama 必须用 host.docker.internal,不能用 127.0.0.1
- LOCAL_BASE_URL=${LOCAL_BASE_URL:-}
- LOCAL_API_KEY=${LOCAL_API_KEY:-ollama}
# 经济参数(可选覆盖)
- EVOTOWN_INITIAL_BALANCE=${EVOTOWN_INITIAL_BALANCE:-100}
- EVOTOWN_REWARD_COMPLETE=${EVOTOWN_REWARD_COMPLETE:-10}
- EVOTOWN_PENALTY_FAIL=${EVOTOWN_PENALTY_FAIL:-5}
- EVOTOWN_COST_ACCEPT=${EVOTOWN_COST_ACCEPT:-5}
- EVOTOWN_ELIMINATE_ON_ZERO=${EVOTOWN_ELIMINATE_ON_ZERO:-true}
# ── 生产稳定性参数 ─────────────────────────────────────────────
# 数据目录(SQLite + social_log 写入路径,必须与 volumes 保持一致)
- EVOTOWN_DATA_DIR=/app/data
# LLM 并发限流(防止 429 突发;默认 5,高配机器可调至 8-10)
- LLM_MAX_CONCURRENCY=${LLM_MAX_CONCURRENCY:-5}
# 单任务最大工具调用步数(超限强制失败,防止 agent 死循环)
- EVOTOWN_MAX_TOOL_CALLS=${EVOTOWN_MAX_TOOL_CALLS:-25}
# Agent 进程内存看门狗(每 N 秒检查一次,超过阈值 MB 触发软重启)
- MEM_WATCHDOG_INTERVAL_SEC=${MEM_WATCHDOG_INTERVAL_SEC:-300}
- AGENT_MEM_THRESHOLD_MB=${AGENT_MEM_THRESHOLD_MB:-300}
# 安全配置
- ADMIN_TOKEN=${ADMIN_TOKEN:-}
- CORS_ORIGINS=${CORS_ORIGINS:-*}
# 使用定制 seccomp profile,允许 bubblewrap (bwrap) 创建 user namespace,
# 同时拦截最危险的内核级 syscall(kexec / module load / perf_event 等)。
# 比 seccomp:unconfined 更安全:默认 ALLOW 但明确 DENY 高危操作。
# bwrap 内部还会对 skill 子进程施加独立的 seccomp BPF 过滤(见 linux.rs)。
cap_add:
- SYS_ADMIN # bwrap 创建 user namespace 所需(mount --make-slave /)
security_opt:
- seccomp:./seccomp-bwrap.json
volumes:
# 进化产物持久化
- evotown_arena:/root/.skilllite/arena
# 实验数据持久化(SQLite WAL + social_log.jsonl)
# 关键:容器重启后数据不丢失;可直接在宿主机 ./data/ 查看/备份文件
- ./data:/app/data
# 录制回放持久化
- evotown_replays:/app/replays
# 运行日志持久化(便于宿主机直接 tail -f 或接入日志系统)
- ./logs:/app/logs
expose:
- "8765"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8765/health')"]
interval: 15s
timeout: 10s
retries: 5
start_period: 15s
# ── Frontend: Nginx + React build ──────────────────────────────
frontend:
build:
context: .
dockerfile: Dockerfile.frontend
restart: unless-stopped
ports:
- "${PORT:-8080}:80"
# 前端产物 + nginx 配置全部内置在 Docker 镜像中,
# 不再挂载本地文件,docker compose up -d --build 即可更新。
depends_on:
backend:
condition: service_healthy
volumes:
evotown_arena:
evotown_replays: