docker-compose.yml
Rama main · réplica de lectura del repositorio original.
services:
toolmesh:
image: ghcr.io/dunkelcloud/toolmesh:latest
# To build locally instead of pulling the image, comment the line above
# and uncomment the next line:
# build: .
restart: unless-stopped
# Bound total memory so a runaway sandbox allocation (composite/code-mode
# JS has no per-runtime heap cap) is contained to this auto-restarting
# container instead of OOM-killing the host. GOMEMLIMIT below is a soft
# limit (~75% of mem_limit) so the GC reclaims and throttles first.
mem_limit: 1g
ports:
- "${TOOLMESH_PORT:-8123}:8080"
# Prometheus metrics — runs on a separate listener so the scraper does
# not need to traverse the public auth-protected MCP port. The endpoint
# is unauthenticated, so the host port is bound to 127.0.0.1 by default:
# reachable from the local host (and Prometheus on this Docker network via
# the service name), but never exposed on a public interface. Override
# TOOLMESH_METRICS_HOST=0.0.0.0 only if you deliberately scrape from
# another host and have firewalled the port yourself.
- "${TOOLMESH_METRICS_HOST:-127.0.0.1}:${TOOLMESH_METRICS_PORT:-9090}:9090"
# Every value from .env ends up in the container configuration on disk
# (docker inspect shows it). To keep credentials out of it, use the
# command credential store: docker-compose.override.yml.example has the
# mounts it needs, docs/configuration.md ("Command store") the rest.
env_file: .env
environment:
# Soft heap limit (~75% of mem_limit) so the Go GC throttles allocation
# before the container hard limit triggers an OOM kill.
- GOMEMLIMIT=${GOMEMLIMIT:-768MiB}
- AUDIT_STORE=${AUDIT_STORE:-log}
- TOOLMESH_DATA_DIR=/app/data
- TOOLMESH_METRICS_ENABLED=${TOOLMESH_METRICS_ENABLED:-true}
- TOOLMESH_METRICS_LABEL_TOOL=${TOOLMESH_METRICS_LABEL_TOOL:-true}
- TOOLMESH_DEBUG_TOOLS=${TOOLMESH_DEBUG_TOOLS:-false}
depends_on:
keydb:
condition: service_healthy
volumes:
- ./config:/app/config:ro
- ./config/policies:/app/policies:ro
- ./tools:/app/tools:ro
- ./dadl:/app/dadl:ro
- ./data:/app/data
# Demo MCP backend (optional — uncomment to enable)
# Note: mcp/everything has a known crash loop with SSE transport.
# Use only for testing, not in production.
# everything:
# image: mcp/everything
# entrypoint: ["node", "dist/sse.js"]
# ports:
# - "3001:3001"
# --- External OpenFGA server (TOOLMESH_AUTHZ_MODE=external) ---
# Not needed by default: authorization runs inside ToolMesh
# (TOOLMESH_AUTHZ_MODE=embedded, data in ./data/authz.db). Use these services
# only to run your own OpenFGA server, e.g. one shared with other
# applications.
# To enable:
# 1. Uncomment the OpenFGA services and the mysqldata volume below.
# 2. docker compose up -d
# 3. ./config/openfga/setup.sh
# 4. Copy OPENFGA_STORE_ID from the output into .env and set
# TOOLMESH_AUTHZ_MODE=external and OPENFGA_API_URL=http://openfga:8080.
# 5. docker compose down && docker compose up -d
#
# openfga-migrate:
# image: openfga/openfga:latest
# command: migrate
# environment:
# - OPENFGA_DATASTORE_ENGINE=mysql
# - OPENFGA_DATASTORE_URI=${OPENFGA_DB_USER:-openfga}:${OPENFGA_DB_PASSWORD:-openfga}@tcp(mysql:3306)/${OPENFGA_DB_NAME:-openfga}?parseTime=true
# depends_on:
# mysql:
# condition: service_healthy
#
# openfga:
# image: openfga/openfga:latest
# ports:
# - "8081:8080" # API — expose only if you need host access
# command: run
# environment:
# - OPENFGA_DATASTORE_ENGINE=mysql
# - OPENFGA_DATASTORE_URI=${OPENFGA_DB_USER:-openfga}:${OPENFGA_DB_PASSWORD:-openfga}@tcp(mysql:3306)/${OPENFGA_DB_NAME:-openfga}?parseTime=true
# depends_on:
# openfga-migrate:
# condition: service_completed_successfully
# healthcheck:
# test: ["CMD", "/usr/local/bin/grpc_health_probe", "-addr=:8081"]
# interval: 5s
# timeout: 3s
# retries: 5
#
# mysql:
# image: mysql:8.0
# environment:
# MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
# MYSQL_DATABASE: ${OPENFGA_DB_NAME:-openfga}
# MYSQL_USER: ${OPENFGA_DB_USER:-openfga}
# MYSQL_PASSWORD: ${OPENFGA_DB_PASSWORD:-openfga}
# volumes:
# - mysqldata:/var/lib/mysql
# healthcheck:
# test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
# interval: 10s
# timeout: 5s
# retries: 10
# start_period: 30s
keydb:
image: eqalpha/keydb:alpine
restart: unless-stopped
# No ports exposed — only accessible from within the Docker network.
command: keydb-server --appendonly yes
volumes:
- keydbdata:/data
healthcheck:
test: ["CMD", "keydb-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
# --- Reverse proxy (uncomment for HTTPS / Claude.ai access) ---
# caddy:
# image: caddy:2-alpine
# ports:
# - "443:443"
# - "80:80"
# volumes:
# - ./Caddyfile:/etc/caddy/Caddyfile:ro
# - caddy_data:/data
# - caddy_config:/config
# depends_on:
# - toolmesh
volumes:
# mysqldata: # uncomment together with the OpenFGA services above
keydbdata:
# caddy_data:
# caddy_config: