-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
123 lines (109 loc) · 3.57 KB
/
Copy pathdocker-compose.yml
File metadata and controls
123 lines (109 loc) · 3.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
# ============================================================================
# StockLens — single-host docker compose stack.
#
# Usage:
# cp .env.example .env # then fill in API keys, STOCK_LIST, ...
# docker compose up -d --build
# docker compose logs -f stocklens
# docker compose down
#
# Services:
# tickbridge → market-data daemon (refreshes DB, serves RPC + ws)
# stocklens → API + heatmap UI; reads data via TickbridgeClient
#
# The two services share ``./data`` so they see the same SQLite file.
# ``tickbridge`` is the **sole writer** for the tb_* tables; stocklens
# only reads from it via HTTP.
#
# Volumes:
# ./data → persistent SQLite DB + diskcache (data/kvcache/) + portfolio
# ./logs → rotating log files
# .env → all runtime configuration (read-only, never baked into image)
# ============================================================================
services:
tickbridge:
build:
context: ./tickbridge-server
dockerfile: docker/Dockerfile
image: tickbridge-server:latest
container_name: tickbridge
restart: unless-stopped
environment:
- TICKBRIDGE_DB_PATH=/app/data/stock_analysis.db
- TICKBRIDGE_HOST=0.0.0.0
- TICKBRIDGE_PORT=8001
- TICKBRIDGE_REFRESH_PERIOD_SECONDS=${TICKBRIDGE_REFRESH_PERIOD_SECONDS:-3600}
- TICKBRIDGE_BOOT_REFRESH=${TICKBRIDGE_BOOT_REFRESH:-true}
- TICKBRIDGE_LOG_LEVEL=${TICKBRIDGE_LOG_LEVEL:-INFO}
# Only stocklens (and the host, for debugging) needs to reach this.
ports:
- "127.0.0.1:8001:8001"
volumes:
- ./data:/app/data
- ./logs:/app/logs
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8001/v1/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
stocklens:
build:
context: .
dockerfile: Dockerfile
image: stocklens:latest
container_name: stocklens
restart: unless-stopped
depends_on:
tickbridge:
condition: service_healthy
# All configuration comes from .env — never edit values inline so
# rebuilds don't change behaviour silently.
env_file:
- .env
# Wire stocklens to the tickbridge daemon by service name. The
# actual TickbridgeClient construction reads these env vars.
environment:
- TICKBRIDGE_URL=http://tickbridge:8001
- TICKBRIDGE_WS_URL=ws://tickbridge:8001/v1/subscribe
# Bind the web port to the host. Override via .env (HOST_PORT=8080).
ports:
- "${HOST_PORT:-8000}:8000"
# Mutable state lives outside the container so upgrades are
# zero-data-loss. Both directories are created on first run if absent.
volumes:
- ./data:/app/data
- ./logs:/app/logs
# Resource caps prevent runaway LLM-driven workloads from starving
# the host. Tune in .env if you have more headroom.
deploy:
resources:
limits:
cpus: "${STOCKLENS_CPU_LIMIT:-2.0}"
memory: "${STOCKLENS_MEM_LIMIT:-2g}"
# Healthcheck mirrors what the Dockerfile defines so `docker compose
# ps` shows accurate status.
healthcheck:
test:
- CMD
- curl
- --fail
- --silent
- --max-time
- "4"
- http://127.0.0.1:8000/api/health
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
# Don't flood the host journal — rotate aggressively.
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"