Repository navigation
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
65 lines (59 loc) · 2.59 KB
/
Copy pathdocker-compose.yml
File metadata and controls
65 lines (59 loc) · 2.59 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
# docker-compose.yml – production-style deployment of task-loop.
#
# The key point: in production we NEVER read a .env file. The container is
# started with TASKLOOP_ENV=production (which short-circuits the .env loader
# before python-dotenv is even imported), and every other setting arrives as
# a real environment variable. .env is also excluded from the build context
# via .dockerignore, so it physically can't be inside the image.
#
# Secrets are injected two ways here for illustration:
# - simple values inline (works, but they end up visible in the compose
# file / `docker inspect`)
# - the "preferred" way: an env_file that ISN'T committed, e.g.
# .env.production, referenced via `env_file:` — or injected by your
# orchestrator (k8s Secret, docker secret, CI secret).
#
# Usage:
# docker compose up -d --build
#
# The catalog (tools.yaml) is mounted read-only so you can tweak server URLs
# and tool definitions without rebuilding the image.
#
# For a plain local dev run you don't need Docker at all: `cp .env.example
# .env` and `taskloop web`. This compose is the *deployed* shape.
services:
taskloop:
build: .
image: taskloop:latest
container_name: taskloop
restart: unless-stopped
ports:
- "${TASKLOOP_WEB_PORT:-8000}:8000"
volumes:
# Runtime data (SQLite DB + state.json) lives here; persisted across
# restarts. Point this at a named volume / NAS / managed disk in prod.
- taskloop-data:/app/data
# Catalog override — tweak servers/tools without rebuilding.
- ./tools.yaml:/app/tools.yaml:ro
environment:
# Production: never load a .env inside the container.
TASKLOOP_ENV: production
# LLM endpoint (OpenAI-compatible).
TASKLOOP_LLM_BASE_URL: ${TASKLOOP_LLM_BASE_URL:-http://host.docker.internal:11434/v1}
TASKLOOP_LLM_API_KEY: ${TASKLOOP_LLM_API_KEY:-ollama}
TASKLOOP_LLM_MODEL: ${TASKLOOP_LLM_MODEL:-llama3.2}
# Concurrency / safety / scheduler.
TASKLOOP_LLM_MAX_CONCURRENCY: ${TASKLOOP_LLM_MAX_CONCURRENCY:-1}
TASKLOOP_MAX_STEPS: ${TASKLOOP_MAX_STEPS:-50}
TASKLOOP_TICK_SECONDS: ${TASKLOOP_TICK_SECONDS:-5.0}
# Tool server locations + secrets.
TASKLOOP_MCP_URL: ${TASKLOOP_MCP_URL:-http://mcp-server:8627}
TASKLOOP_MCP_API_KEY: ${TASKLOOP_MCP_API_KEY:-}
TASKLOOP_VITAL_URL: ${TASKLOOP_VITAL_URL:-http://vital:9000}
TASKLOOP_VITAL_API_KEY: ${TASKLOOP_VITAL_API_KEY:-}
# Optional: pull secrets from an uncommitted file instead of inline.
# env_file:
# - path: .env.production
# required: false
volumes:
taskloop-data: