-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
39 lines (38 loc) · 1.64 KB
/
Copy pathdocker-compose.yml
File metadata and controls
39 lines (38 loc) · 1.64 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
services:
tracker:
build: .
image: llm-usage-tracker
container_name: llm-usage-tracker
restart: unless-stopped
ports:
- "3789:3000"
environment:
# Match the host timezone — SQLite 'localtime' day bucketing must agree
# with the user's calendar or sessions land on the wrong day
TZ: ${TZ:-Asia/Phnom_Penh}
# Provides ENCRYPTION_KEY — the standalone server doesn't load dotenv files,
# and without a stable key the stored credentials can't be decrypted
env_file:
- .env.local
volumes:
# SQLite DB + encrypted credentials. This MUST be a named volume, not a
# host bind mount: WAL mode keeps its wal-index in an mmap'd -shm file,
# and Docker Desktop's macOS bind mounts (VirtioFS) don't give mmap the
# coherence SQLite needs. Reads then return garbage pages and every query
# dies with SQLITE_NOTADB/SQLITE_CORRUPT while the file on disk is fine.
# Named volumes live on real ext4 inside the VM, where WAL works.
# For host access to the DB, use `npm run db:export`.
- llm-tracker-data:/data
# Codex CLI login, read-only — tokens stay managed by `codex` on the host
- ~/.codex:/codex:ro
# Claude Code transcripts, read-only — the claude-watcher derives
# per-model token usage from them (hooks don't carry token counts)
- ~/.claude/projects:/claude-projects:ro
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/api/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
interval: 30s
timeout: 5s
start_period: 30s
retries: 3
volumes:
llm-tracker-data: