-
Notifications
You must be signed in to change notification settings - Fork 249
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
194 lines (190 loc) · 10.5 KB
/
Copy pathdocker-compose.yml
File metadata and controls
194 lines (190 loc) · 10.5 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
# ============================================================================
# ⚠️ DATABASE ENGINE: PostgreSQL (was MySQL before)
#
# This stack now runs on PostgreSQL 16. Switching the DB engine is a BREAKING
# change for existing deployments: `docker compose up -d` on a host that
# previously ran the MySQL stack starts a FRESH, EMPTY PostgreSQL volume
# (postgres_data). The old `mysql_data` volume is NOT read and the app
# re-seeds default data — existing data is not lost, but it is also NOT
# visible to the new stack.
#
# Treat this as FRESH-INSTALL-ONLY. To carry data across from a MySQL
# deployment, dump the OLD stack BEFORE pulling this change, e.g.:
# docker compose exec mysql mysqldump -u"$DB_USERNAME" -p"$DB_PASSWORD" "$DB_NAME" > mateclaw-mysql.sql
# then load into PostgreSQL with a cross-engine tool such as pgloader —
# there is no automatic MySQL → PostgreSQL migration here. Alternatively,
# keep running MySQL by pinning your checkout to a pre-switch tag and setting
# SPRING_PROFILES_ACTIVE=mysql (the mysql Spring profile remains supported).
# ============================================================================
services:
# PostgreSQL 数据库
#
# ⚠️ 密码通过环境变量传入,必须从 .env 文件提供。首次部署前:
# 1. cp .env.example .env
# 2. 编辑 .env 把 DB_ADMIN_PASSWORD / DB_PASSWORD 改成强密码
# 未设置会直接在 `docker compose up` 时报错,避免把默认密码带到生产环境。
postgres:
image: postgres:16
container_name: mateclaw-postgres
restart: unless-stopped
environment:
# Bootstrap/superuser — owns the cluster, used only for init + admin tasks.
POSTGRES_DB: ${DB_NAME:-mateclaw}
POSTGRES_USER: ${DB_ADMIN_USERNAME:-mateclaw_admin}
POSTGRES_PASSWORD: ${DB_ADMIN_PASSWORD:?DB_ADMIN_PASSWORD is required in .env}
# Least-privilege application role created by the init script below; this
# is the account the server connects with (NOT a superuser).
APP_DB_USERNAME: ${DB_USERNAME:-mateclaw}
APP_DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD is required in .env}
TZ: Asia/Shanghai
# No host port on purpose — the DB is only reachable from the compose
# network. For ad-hoc inspection use `docker compose exec postgres psql`,
# or temporarily add: ports: ["127.0.0.1:5432:5432"]
volumes:
- postgres_data:/var/lib/postgresql/data
# Runs once on first init (empty data dir): creates the restricted app
# role and the mateclaw schema it owns. See docker/postgres/init/.
- ./docker/postgres/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_ADMIN_USERNAME:-mateclaw_admin} -d ${DB_NAME:-mateclaw}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- mateclaw-net
# SearXNG 搜索引擎(keyless 搜索 provider)
#
# The custom image at docker/searxng/ bakes in settings.yml so the sidecar
# works out of the box (upstream image ships JSON disabled + Limiter enabled,
# both of which silently break mateclaw's SearXNGSearchProvider).
# No host bind-mount — edit docker/searxng/settings.yml and rebuild.
# Internal-only: the app reaches it via the compose network. To debug from
# the host, temporarily add: ports: ["127.0.0.1:8088:8080"]
searxng:
build:
context: ./docker/searxng
container_name: mateclaw-searxng
restart: unless-stopped
environment:
- SEARXNG_BASE_URL=http://searxng:8080
- SEARXNG_SECRET=${SEARXNG_SECRET:-mateclaw-dev-searxng-secret-change-me}
- UWSGI_WORKERS=2
- UWSGI_THREADS=4
healthcheck:
# Healthz needs json format, so this also doubles as an integration check.
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/healthz"]
interval: 30s
timeout: 5s
retries: 3
networks:
- mateclaw-net
# MateClaw 后端服务
mateclaw-server:
build:
context: .
dockerfile: mateclaw-server/Dockerfile
args:
MAVEN_FLAGS: ${MAVEN_FLAGS:-}
container_name: mateclaw-server
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
searxng:
condition: service_healthy
environment:
SPRING_PROFILES_ACTIVE: postgres
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: ${DB_NAME:-mateclaw}
DB_USERNAME: ${DB_USERNAME:-mateclaw}
DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD is required in .env}
# LLM provider keys (DashScope / OpenAI / Anthropic / DeepSeek / Kimi / …) are
# NOT configured via env vars. After startup, add providers in the admin UI:
# Settings → Models → Add Provider
# Keys are stored in mate_model_provider and hot-reloaded.
SERPER_API_KEY: ${SERPER_API_KEY:-}
TAVILY_API_KEY: ${TAVILY_API_KEY:-}
JWT_SECRET: ${JWT_SECRET:-}
MATECLAW_CORS_ALLOWED_ORIGINS: ${MATECLAW_CORS_ALLOWED_ORIGINS:-}
# SearXNG: tell the app where to reach the sidecar container
SEARXNG_BASE_URL: ${SEARXNG_BASE_URL:-http://searxng:8080}
# Browser automation: the runtime image (mcr.microsoft.com/playwright:*)
# bakes Chromium + system libs + fonts in, so the tool works out of the box.
# Override these if you want to attach to an external Chrome (CDP sidecar):
MATECLAW_BROWSER_CDP_URL: ${MATECLAW_BROWSER_CDP_URL:-}
MATECLAW_BROWSER_CHROME_PATH: ${MATECLAW_BROWSER_CHROME_PATH:-}
MATECLAW_BROWSER_CHANNEL: ${MATECLAW_BROWSER_CHANNEL:-}
# SSRF / TLS relaxations for isolated LAN / on-prem deployments.
# Both default to false (strict mode, public-internet safe).
# The .env file uses the PLAYWRIGHT_* prefix (component-oriented naming,
# not product-oriented) — here we translate to the MATECLAW_BROWSER_*
# container env that Spring Boot relaxed-binding maps to BrowserProperties.
# - PLAYWRIGHT_ALLOW_PRIVATE_NETWORK=true: allow loopback / private / link-local
# addresses through the browser SSRF guard. Cloud-metadata endpoints stay
# blocked. Turn on when the agent must drive http://192.168.x.x:port style
# internal services and has no path to the public internet.
# - PLAYWRIGHT_IGNORE_HTTPS_ERRORS=true: ignore HTTPS certificate errors.
# Auto-enables --ignore-certificate-errors at the Chromium command line
# when ALLOW_PRIVATE_NETWORK is also true (so CDP-attached external
# browsers benefit too). Leave false on internet-facing deployments.
MATECLAW_BROWSER_ALLOW_PRIVATE_NETWORK: ${PLAYWRIGHT_ALLOW_PRIVATE_NETWORK:-false}
MATECLAW_BROWSER_IGNORE_HTTPS_ERRORS: ${PLAYWRIGHT_IGNORE_HTTPS_ERRORS:-false}
# Playwright action / navigation timeouts (seconds). Increase for slow
# LAN or large-page scenarios. Defaults match Playwright's own (30s).
MATECLAW_BROWSER_DEFAULT_TIMEOUT_SECONDS: ${PLAYWRIGHT_DEFAULT_TIMEOUT_SECONDS:-30}
MATECLAW_BROWSER_DEFAULT_NAVIGATION_TIMEOUT_SECONDS: ${PLAYWRIGHT_NAVIGATION_TIMEOUT_SECONDS:-30}
# Hard cap on the textual snapshot returned by action=snapshot. Content
# beyond this length is dropped with a truncated:true flag and a hint to
# retry with selector. Results > framework spill threshold (~8000 chars)
# are further spilt to disk by ToolResultStorage.
MATECLAW_BROWSER_SNAPSHOT_MAX_LENGTH: ${PLAYWRIGHT_SNAPSHOT_MAX_LENGTH:-20000}
# OAuth 模式默认保持 auto:localhost 访问走 LOCAL,IP/域名访问走 DEVICE_CODE。
# 本机 Docker 若要强制使用 localhost:1455 回调,可在 .env 显式设为 local。
MATECLAW_OAUTH_OPENAI_DEPLOYMENT_MODE: ${MATECLAW_OAUTH_OPENAI_DEPLOYMENT_MODE:-}
MATECLAW_OAUTH_OPENAI_CALLBACK_BIND_HOST: ${MATECLAW_OAUTH_OPENAI_CALLBACK_BIND_HOST:-0.0.0.0}
# Wiki 知识库目录扫描白名单(逗号分隔,留空则禁止所有目录扫描)。
# 示例:MATE_WIKI_ALLOWED_SOURCE_ROOTS=/data/wiki,/opt/docs
# 记得同步在 volumes 里把宿主机路径挂进容器。
MATE_WIKI_ALLOWED_SOURCE_ROOTS: ${MATE_WIKI_ALLOWED_SOURCE_ROOTS:-}
# Wiki 知识源自动同步总开关(运维总闸,默认关)。AND 语义:全局开关与
# 每个知识库自己的「自动同步」开关都开,该库才会被定时扫描。
# 间隔单位毫秒,默认 5 分钟。
MATE_WIKI_WATCHER_ENABLED: ${MATE_WIKI_WATCHER_ENABLED:-false}
MATE_WIKI_WATCHER_INTERVAL_MS: ${MATE_WIKI_WATCHER_INTERVAL_MS:-300000}
# Skill 工作区根目录。放在 /app/data 下,让现有的 server_data 卷一并持久化
# 已安装的 skill、运行时积累的 LESSONS.md 以及 skill 运行产物,容器重启不丢。
# 内置 skill 仍由 JAR classpath 每次启动现场释放,空卷不会丢内置文件。
MATECLAW_SKILL_WORKSPACE_ROOT: ${MATECLAW_SKILL_WORKSPACE_ROOT:-/app/data/skills}
# Skill ZIP 上传/安装大小上限(MB)。解包过程整包缓存在内存里,
# max-total 调多大,单次安装的峰值内存就可能吃多大。
MATECLAW_SKILL_UPLOAD_MAX_ENTRY_SIZE_MB: ${MATECLAW_SKILL_UPLOAD_MAX_ENTRY_SIZE_MB:-1}
MATECLAW_SKILL_UPLOAD_MAX_TOTAL_SIZE_MB: ${MATECLAW_SKILL_UPLOAD_MAX_TOTAL_SIZE_MB:-50}
# pip 镜像源配置(可选)。skill 里的 Python 脚本缺包时 pip install 会走这个源。
# 留空则用 PyPI 默认源(pypi.org)。pip 原生读 PIP_INDEX_URL / PIP_TRUSTED_HOST
# 环境变量,容器内所有进程(JVM、Python 子进程、bash)自动继承,无需额外配置。
# HTTP 源会自动从 URL 推导 PIP_TRUSTED_HOST;自签 HTTPS 需手动填。
# - 互联网加速:PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
# - 局域网私有源:PIP_INDEX_URL=http://192.168.1.100:8080/simple(trusted-host 自动推导)
PIP_INDEX_URL: ${PIP_INDEX_URL:-}
PIP_TRUSTED_HOST: ${PIP_TRUSTED_HOST:-}
# Chromium needs a real /dev/shm. Docker defaults to 64MB which causes
# SIGBUS / "Target page closed" errors under load. 2GB is the usual
# recommendation for Playwright / headless chrome.
shm_size: 2gb
ports:
- "18080:18088" # host:container — app listens on 18088 inside the container
- "1455:1455"
volumes:
# server_data covers /app/data — wiki-uploads AND the skill workspace
# (MATECLAW_SKILL_WORKSPACE_ROOT=/app/data/skills above), so a single
# volume persists everything. No separate skills volume needed.
- server_data:/app/data
networks:
- mateclaw-net
volumes:
postgres_data:
server_data:
networks:
mateclaw-net:
driver: bridge