-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
130 lines (124 loc) · 4.09 KB
/
Copy pathdocker-compose.yml
File metadata and controls
130 lines (124 loc) · 4.09 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
services:
kafka:
image: apache/kafka:3.9.1
container_name: fraud-kafka
ports:
- "9092:9092"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,INTERNAL://:19092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,INTERNAL://kafka:19092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9093
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
healthcheck:
test: ["CMD-SHELL", "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 > /dev/null 2>&1"]
interval: 10s
timeout: 10s
retries: 10
start_period: 20s
db:
image: postgres:16
container_name: fraud-db
environment:
POSTGRES_DB: ${DB_NAME:-frauddb}
POSTGRES_USER: ${DB_USER:-fraud}
POSTGRES_PASSWORD: ${DB_PASSWORD:-fraudpass}
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-fraud} -d ${DB_NAME:-frauddb}"]
interval: 5s
timeout: 5s
retries: 12
app:
build: .
container_name: fraud-app
ports:
- "8000:8000"
environment:
DB_HOST: db
DB_PORT: 5432
DB_NAME: ${DB_NAME:-frauddb}
DB_USER: ${DB_USER:-fraud}
DB_PASSWORD: ${DB_PASSWORD:-fraudpass}
KAFKA_BOOTSTRAP_SERVERS: ${KAFKA_BOOTSTRAP_SERVERS:-kafka:19092}
FRAUD_THRESHOLD: ${FRAUD_THRESHOLD:-0.7}
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-}
TELEGRAM_CHAT_ID: ${TELEGRAM_CHAT_ID:-}
volumes:
- ./model:/app/model
- ./data:/app/data # needed by POST /model/retrain; dataset is .dockerignore'd
depends_on:
kafka:
condition: service_healthy
db:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=3)\""]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# Producer and consumer run as separate services (not background
# processes in the app container): CLAUDE.md mandates they be separate
# processes, and separate services give independent logs, restart
# policies, and scaling — same image, different command.
producer:
build: .
container_name: fraud-producer
command: python -m streaming.producer
environment:
KAFKA_BOOTSTRAP_SERVERS: ${KAFKA_BOOTSTRAP_SERVERS:-kafka:19092}
PRODUCER_LIMIT: ${PRODUCER_LIMIT:-100}
PRODUCER_INTERVAL: ${PRODUCER_INTERVAL:-1.0}
volumes:
- ./data:/app/data # dataset is .dockerignore'd; mount it instead
depends_on:
kafka:
condition: service_healthy
restart: "no" # finite run: exits after PRODUCER_LIMIT messages
consumer:
build: .
container_name: fraud-consumer
command: python -m streaming.consumer
environment:
DB_HOST: db
DB_PORT: 5432
DB_NAME: ${DB_NAME:-frauddb}
DB_USER: ${DB_USER:-fraud}
DB_PASSWORD: ${DB_PASSWORD:-fraudpass}
KAFKA_BOOTSTRAP_SERVERS: ${KAFKA_BOOTSTRAP_SERVERS:-kafka:19092}
FRAUD_THRESHOLD: ${FRAUD_THRESHOLD:-0.7}
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-}
TELEGRAM_CHAT_ID: ${TELEGRAM_CHAT_ID:-}
volumes:
- ./model:/app/model # picks up retrained model.joblib without rebuild
depends_on:
kafka:
condition: service_healthy
db:
condition: service_healthy
restart: unless-stopped
dashboard:
build: .
container_name: fraud-dashboard
command: python app.py
ports:
- "8050:8050"
environment:
API_URL: ${API_URL:-http://app:8000}
depends_on:
app:
condition: service_healthy
restart: unless-stopped
volumes:
pgdata: