-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
158 lines (149 loc) · 6.57 KB
/
Copy pathdocker-compose.yml
File metadata and controls
158 lines (149 loc) · 6.57 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
# =============================================================================
# AnythingMCP — Full Stack Deployment (Single Container)
# =============================================================================
# Usage: docker compose up -d
# UI: http://localhost:3000
# API: http://localhost:4000
# MCP: http://localhost:4000/mcp
# =============================================================================
# Project name — also the prefix for the auto-created network and volumes.
# Override COMPOSE_PROJECT_NAME (in .env or the environment) to run more than
# one AnythingMCP stack on the same host without name collisions.
name: ${COMPOSE_PROJECT_NAME:-amcp}
services:
# Caddy Reverse Proxy (optional — enables HTTPS with automatic Let's Encrypt)
# Activated by COMPOSE_PROFILES=proxy in .env (setup.sh sets this automatically)
caddy:
image: caddy:2-alpine
profiles: ["proxy"]
container_name: ${COMPOSE_PROJECT_NAME:-amcp}-caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
app:
condition: service_healthy
restart: unless-stopped
# NestJS Backend + Next.js Frontend (single container)
app:
image: helpcodeai/anythingmcp:latest
build:
context: .
dockerfile: Dockerfile
container_name: ${COMPOSE_PROJECT_NAME:-amcp}-app
# Bind published ports to loopback by default so the API/MCP endpoint is
# not exposed on every network interface out of the box. To reach it from
# the LAN or the public internet, set APP_BIND_IP=0.0.0.0 in .env (and put
# it behind the Caddy proxy / a firewall). The Caddy service talks to the
# app over the internal Docker network, so it is unaffected by this bind.
ports:
- "${APP_BIND_IP:-127.0.0.1}:${FRONTEND_PORT:-3000}:3000"
- "${APP_BIND_IP:-127.0.0.1}:${BACKEND_PORT:-4000}:4000"
environment:
- NODE_ENV=production
- PORT=4000
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:4000}
- DATABASE_URL=postgresql://amcp:${POSTGRES_PASSWORD:-amcp}@postgres:5432/anythingmcp
- JWT_SECRET=${JWT_SECRET:-change-me-in-production-min-32-chars}
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-change-me-in-production-exactly-32}
- CORS_ORIGIN=${CORS_ORIGIN:-http://localhost:3000}
- SERVER_URL=${SERVER_URL:-http://localhost:4000}
- FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000}
# MCP Authentication (oauth2 | legacy | both | none)
# In `legacy`/`both` mode the /mcp endpoint requires MCP_API_KEY or
# MCP_BEARER_TOKEN. If neither is set, requests are REFUSED (401) unless
# MCP_ALLOW_ANONYMOUS=true is set explicitly — this avoids silently
# exposing configured MCP tools to unauthenticated network clients.
- MCP_AUTH_MODE=${MCP_AUTH_MODE:-legacy}
- MCP_API_KEY=${MCP_API_KEY:-}
- MCP_BEARER_TOKEN=${MCP_BEARER_TOKEN:-}
# Set to true ONLY for trusted local/dev use to allow unauthenticated
# /mcp access when no MCP credentials are configured (legacy mode).
- MCP_ALLOW_ANONYMOUS=${MCP_ALLOW_ANONYMOUS:-false}
# Registration (false = invite-only after first admin, true = anyone can register)
- ALLOW_OPEN_REGISTRATION=${ALLOW_OPEN_REGISTRATION:-false}
# Uncomment to enable Redis (optional — used for response caching and rate limiting)
# - REDIS_URL=redis://redis:6379
# Deutsche Bahn connector: URL of a MOTIS instance. Set together with
# COMPOSE_PROFILES=motis to run the bundled one (see deploy/motis); the
# adapter then fills its MOTIS_URL in automatically at import. Leave
# unset to be asked for a URL when installing the adapter.
- MOTIS_INTERNAL_URL=${MOTIS_INTERNAL_URL:-}
# Hosts the SSRF guard may reach even though they resolve to a private
# address. Needed for the bundled MOTIS (`motis`) and any other API you
# run on the same Docker network.
- SSRF_ALLOWED_HOSTS=${SSRF_ALLOWED_HOSTS:-}
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/health"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
restart: unless-stopped
# PostgreSQL Database
postgres:
image: postgres:17-alpine
container_name: ${COMPOSE_PROJECT_NAME:-amcp}-postgres
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=amcp
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-amcp}
- POSTGRES_DB=anythingmcp
healthcheck:
test: ["CMD-SHELL", "pg_isready -U amcp -d anythingmcp"]
interval: 5s
timeout: 3s
retries: 5
restart: unless-stopped
# MOTIS routing engine for the Deutsche Bahn connector (optional).
# Activated by COMPOSE_PROFILES=motis in .env, together with
# MOTIS_INTERNAL_URL=http://motis:8080 and SSRF_ALLOWED_HOSTS=motis. Pulls
# the open gtfs.de train timetable on first boot and refreshes it weekly;
# about 12 MB of GTFS, a one-second import, ~100 MB of RAM at rest.
# Details and feed licences: deploy/motis/README.md
motis:
build:
context: ./deploy/motis
image: anythingmcp-motis:2.11.3-1
profiles: ["motis"]
container_name: ${COMPOSE_PROJECT_NAME:-amcp}-motis
volumes:
- motis_data:/data
healthcheck:
# 127.0.0.1, not localhost: MOTIS binds IPv4 only and localhost resolves
# to ::1 first inside the container, so the probe was refused every time.
# /metrics, not /: MOTIS answers 404 on the root, which --spider treats as
# a failure. Between the two, the container reported unhealthy for its
# whole life while serving traffic perfectly.
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://127.0.0.1:8080/metrics"]
interval: 30s
timeout: 5s
retries: 3
start_period: 180s
restart: unless-stopped
# Redis Cache (optional — uncomment to enable response caching and rate limiting)
# redis:
# image: redis:7-alpine
# container_name: ${COMPOSE_PROJECT_NAME:-amcp}-redis
# volumes:
# - redis_data:/data
# healthcheck:
# test: ["CMD", "redis-cli", "ping"]
# interval: 5s
# timeout: 3s
# retries: 5
# restart: unless-stopped
volumes:
postgres_data:
motis_data: # Imported timetable for the optional MOTIS service
caddy_data: # Let's Encrypt certificates (used when Caddy proxy is enabled)
caddy_config: # Caddy configuration cache
# redis_data: # Uncomment if Redis is enabled