-
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathdocker-compose.yaml
More file actions
292 lines (270 loc) · 11.9 KB
/
Copy pathdocker-compose.yaml
File metadata and controls
292 lines (270 loc) · 11.9 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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# ============================================================================
# Docker Compose Configuration for Actual MCP Server
# ============================================================================
# This file provides multiple configurations for running the Actual MCP Server
# with Docker Compose, including both development and production setups.
#
# Usage:
# Development: docker compose --profile dev up
# Production: docker compose --profile production up
# ============================================================================
version: '3.8'
services:
# --------------------------------------------------------------------------
# Actual MCP Server - Development Mode
# --------------------------------------------------------------------------
# Default service for local development with hot-reload and debug logging
mcp-server-dev:
build:
context: .
dockerfile: Dockerfile
container_name: actual-mcp-dev
profiles:
- dev
restart: unless-stopped
ports:
- "3600:3600"
volumes:
# Mount source code for development
- ./src:/app/src:ro
- ./dist:/app/dist
# Required: local cache for the @actual-app/api library.
# The API downloads your budget data locally to run queries; this MUST be a persistent path.
# Canonical container data dir (#228): /app/data, the dir the image creates and chowns.
- ./actual-data:/app/data
# Persist logs
- ./logs:/app/logs
environment:
# Actual Finance connection
# Use the same URL you type in your browser to open Actual Budget.
# Examples:
# http://localhost:5006 - Actual Budget on the same machine (not in Docker)
# http://192.168.1.50:5006 - Actual Budget on another machine on your network
# https://actual.yourdomain.com - Actual Budget with a domain name
# http://actual-main:5006 - Actual Budget in the same Docker network (service name)
# Note: actual-mcp does NOT need to run on the same machine as Actual Budget.
- ACTUAL_SERVER_URL=${ACTUAL_SERVER_URL:-http://actual-main:5006}
- ACTUAL_PASSWORD=${ACTUAL_PASSWORD:?ACTUAL_PASSWORD is required}
- ACTUAL_BUDGET_SYNC_ID=${ACTUAL_BUDGET_SYNC_ID:?ACTUAL_BUDGET_SYNC_ID is required}
# Optional: encryption password for E2E-encrypted default budget.
# #161: if you set this AND the upstream above is http://, the server
# refuses to start (cleartext password). Use an https:// upstream, or add
# - ALLOW_INSECURE_UPSTREAM=true when the hop is a trusted internal network.
# - ACTUAL_BUDGET_PASSWORD=${ACTUAL_BUDGET_PASSWORD}
# Optional: friendly name for the default budget (default: "Default")
# - BUDGET_DEFAULT_NAME=My Main Budget
# ── Multi-Budget Switching (optional) ─────────────────────────────────
# The AI can switch between budgets at runtime with actual_budgets_switch.
# BUDGET_N_SERVER_URL and BUDGET_N_PASSWORD fall back to ACTUAL_* if omitted,
# so budgets on the same server need only NAME and SYNC_ID.
#
# Budget 1 (same server, same password): SERVER_URL and PASSWORD omitted
# - BUDGET_1_NAME=Shared Family Account
# - BUDGET_1_SYNC_ID=${BUDGET_1_SYNC_ID}
#
# Budget 2 (same server, different password): only PASSWORD overridden
# - BUDGET_2_NAME=Business
# - BUDGET_2_PASSWORD=${BUDGET_2_PASSWORD}
# - BUDGET_2_SYNC_ID=${BUDGET_2_SYNC_ID}
#
# Budget 3 (entirely separate Actual server): full override
# - BUDGET_3_NAME=Remote Office
# - BUDGET_3_SERVER_URL=https://actual-office.example.com:5006
# - BUDGET_3_PASSWORD=${BUDGET_3_PASSWORD}
# - BUDGET_3_SYNC_ID=${BUDGET_3_SYNC_ID}
# - BUDGET_3_ENCRYPTION_PASSWORD=${BUDGET_3_ENCRYPTION_PASSWORD}
# MCP Bridge settings
- MCP_BRIDGE_DATA_DIR=/app/data
- MCP_BRIDGE_PORT=3600
- MCP_BRIDGE_BIND_HOST=0.0.0.0
# #242: this dev profile binds 0.0.0.0 with no auth, so it opts out of the
# required-by-default HTTP auth gate to keep `--profile dev up` working. This
# is a local hot-reload stack only; never carry this into a real deployment.
- MCP_ALLOW_UNAUTHENTICATED=true
- MCP_BRIDGE_LOG_LEVEL=debug
- MCP_BRIDGE_STORE_LOGS=true
- MCP_BRIDGE_LOG_DIR=/app/logs
# - MCP_BRIDGE_MAX_FILES=14d
# - MCP_BRIDGE_MAX_LOG_SIZE=20m
# Session management
- MAX_CONCURRENT_SESSIONS=15
# - SESSION_IDLE_TIMEOUT_MINUTES=5
# - ACTUAL_API_CONCURRENCY=5
# Authentication: static Bearer token or OIDC (see README)
# - MCP_SSE_AUTHORIZATION=${MCP_SSE_AUTHORIZATION}
# - AUTH_PROVIDER=none # set to 'oidc' for JWKS JWT validation
# - OIDC_ISSUER=${OIDC_ISSUER} # required when AUTH_PROVIDER=oidc
# - OIDC_RESOURCE=${OIDC_RESOURCE}
# - OIDC_ACCEPTED_AUDIENCES=${OIDC_ACCEPTED_AUDIENCES} # extra 'aud' values (#245)
# - OIDC_JWKS_TRUSTED_HOSTS=${OIDC_JWKS_TRUSTED_HOSTS} # cross-host JWKS, e.g. Google (#254)
# - OIDC_SCOPES=${OIDC_SCOPES}
# - AUTH_BUDGET_ACL=${AUTH_BUDGET_ACL}
# Timezone (set to your local timezone)
- TZ=${TZ:-UTC}
# Development settings
- NODE_ENV=development
networks:
- actual-net
# --------------------------------------------------------------------------
# Actual MCP Server - Production Mode
# --------------------------------------------------------------------------
# Production-ready configuration with secrets management
mcp-server-prod:
image: actual-mcp-server:latest
container_name: actual-mcp-prod
profiles:
- production
restart: unless-stopped
ports:
- "3600:3600"
volumes:
# Required: local cache for the @actual-app/api library.
# The API downloads your budget data locally to run queries; this MUST be a persistent path.
# Canonical container data dir (#228): /app/data, the dir the image creates and chowns.
- mcp-data:/app/data
# Persist logs
- mcp-logs:/app/logs
environment:
# Actual Finance connection.
# Use the same URL you type in your browser to open Actual Budget.
# Examples: http://localhost:5006, http://192.168.1.50:5006, https://actual.yourdomain.com
# If on the same Docker network, use the container service name: http://actual:5006
- ACTUAL_SERVER_URL=${ACTUAL_SERVER_URL:?ACTUAL_SERVER_URL is required}
- ACTUAL_PASSWORD=${ACTUAL_PASSWORD:?ACTUAL_PASSWORD is required}
- ACTUAL_BUDGET_SYNC_ID=${ACTUAL_BUDGET_SYNC_ID:?ACTUAL_BUDGET_SYNC_ID is required}
# Optional: encryption password for E2E-encrypted default budget.
# #161: if you set this AND the upstream above is http://, the server
# refuses to start (cleartext password). Use an https:// upstream, or add
# - ALLOW_INSECURE_UPSTREAM=true when the hop is a trusted internal network.
# - ACTUAL_BUDGET_PASSWORD=${ACTUAL_BUDGET_PASSWORD}
# Optional: friendly name for the default budget (default: "Default")
# - BUDGET_DEFAULT_NAME=My Main Budget
# ── Multi-Budget Switching (optional) ─────────────────────────────────
# The AI can switch between budgets at runtime with actual_budgets_switch.
# BUDGET_N_SERVER_URL and BUDGET_N_PASSWORD fall back to ACTUAL_* if omitted,
# so budgets on the same server need only NAME and SYNC_ID.
#
# Budget 1 (same server, same password): SERVER_URL and PASSWORD omitted
# - BUDGET_1_NAME=Shared Family Account
# - BUDGET_1_SYNC_ID=${BUDGET_1_SYNC_ID}
#
# Budget 2 (same server, different password): only PASSWORD overridden
# - BUDGET_2_NAME=Business
# - BUDGET_2_PASSWORD=${BUDGET_2_PASSWORD}
# - BUDGET_2_SYNC_ID=${BUDGET_2_SYNC_ID}
#
# Budget 3 (entirely separate Actual server): full override
# - BUDGET_3_NAME=Remote Office
# - BUDGET_3_SERVER_URL=https://actual-office.example.com:5006
# - BUDGET_3_PASSWORD=${BUDGET_3_PASSWORD}
# - BUDGET_3_SYNC_ID=${BUDGET_3_SYNC_ID}
# - BUDGET_3_ENCRYPTION_PASSWORD=${BUDGET_3_ENCRYPTION_PASSWORD}
# MCP Bridge settings
- MCP_BRIDGE_DATA_DIR=/app/data
- MCP_BRIDGE_PORT=3600
- MCP_BRIDGE_BIND_HOST=0.0.0.0
# #242: HTTP auth is required-by-default. On this 0.0.0.0 (non-loopback)
# bind the server refuses to start unless you set MCP_SSE_AUTHORIZATION (or
# AUTH_PROVIDER=oidc) below. To run open deliberately behind your own
# authenticating proxy, set MCP_ALLOW_UNAUTHENTICATED=true.
- MCP_BRIDGE_LOG_LEVEL=info
- MCP_BRIDGE_STORE_LOGS=true
- MCP_BRIDGE_LOG_DIR=/app/logs
- MCP_BRIDGE_MAX_FILES=30d
# - MCP_BRIDGE_MAX_LOG_SIZE=20m
# Session management
- MAX_CONCURRENT_SESSIONS=15
# - SESSION_IDLE_TIMEOUT_MINUTES=5
# - ACTUAL_API_CONCURRENCY=5
# Authentication: static Bearer token or OIDC (see README)
# - MCP_SSE_AUTHORIZATION=${MCP_SSE_AUTHORIZATION}
# - AUTH_PROVIDER=none # set to 'oidc' for JWKS JWT validation
# - OIDC_ISSUER=${OIDC_ISSUER} # required when AUTH_PROVIDER=oidc
# - OIDC_RESOURCE=${OIDC_RESOURCE}
# - OIDC_ACCEPTED_AUDIENCES=${OIDC_ACCEPTED_AUDIENCES} # extra 'aud' values (#245)
# - OIDC_JWKS_TRUSTED_HOSTS=${OIDC_JWKS_TRUSTED_HOSTS} # cross-host JWKS, e.g. Google (#254)
# - OIDC_SCOPES=${OIDC_SCOPES}
# - AUTH_BUDGET_ACL=${AUTH_BUDGET_ACL}
# Timezone (set to your local timezone)
- TZ=${TZ:-UTC}
# Production settings
- NODE_ENV=production
networks:
- actual-network
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
# --------------------------------------------------------------------------
# Reverse Proxy - Traefik (Optional)
# --------------------------------------------------------------------------
# Uncomment to add HTTPS and automatic SSL with Let's Encrypt
# traefik:
# image: traefik:v2.10
# container_name: traefik
# profiles:
# - production
# restart: unless-stopped
# ports:
# - "80:80"
# - "443:443"
# volumes:
# - /var/run/docker.sock:/var/run/docker.sock:ro
# - ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
# - ./traefik/acme.json:/acme.json
# networks:
# - actual-network
# ----------------------------------------------------------------------------
# Networks
# ----------------------------------------------------------------------------
networks:
actual-network:
driver: bridge
name: actual-network
librechat-net:
external: true
name: librechat-net
actual-net:
external: true
name: actual-net
# ----------------------------------------------------------------------------
# Volumes
# ----------------------------------------------------------------------------
volumes:
# MCP server data (production)
mcp-data:
driver: local
name: actual-mcp-data
# MCP server logs (production)
mcp-logs:
driver: local
name: actual-mcp-logs
# ============================================================================
# Usage Examples
# ============================================================================
#
# Prerequisites: Have an Actual Budget server running (self-hosted or cloud)
#
# 1. Development mode:
# $ docker compose --profile dev up
#
# 2. Production deployment:
# $ docker compose --profile production up -d
#
# 3. Build custom image:
# $ docker compose build mcp-server-dev
#
# 4. View logs:
# $ docker compose logs -f mcp-server-dev
#
# 5. Stop all services:
# $ docker compose down
#
# 6. Remove all data (CAUTION: This deletes all data):
# $ docker compose down -v
#
# ============================================================================