Repository navigation
Expand file tree
/
Copy pathdocker-compose.classifier.yml
More file actions
77 lines (76 loc) · 3.43 KB
/
Copy pathdocker-compose.classifier.yml
File metadata and controls
77 lines (76 loc) · 3.43 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
# Local-only. Classification half of the split, isolated from prod.
# DB_HOST is pinned to the local `db` service, so a run physically cannot reach
# RDS (settings.py:76 otherwise defaults DB_HOST to the prod RDS endpoint).
# Secrets come from a gitignored .env via ${VAR} substitution - never hardcode.
services:
db:
image: postgres:15
environment:
POSTGRES_DB: vulnerability
POSTGRES_USER: vi
POSTGRES_PASSWORD: vi_local
ports:
- "5433:5432" # host 5433 to avoid clashing with a local postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U vi -d vulnerability"]
interval: 5s
timeout: 3s
retries: 10
classifier:
build:
context: .
dockerfile: Dockerfile.classifier
depends_on:
db:
condition: service_healthy
environment:
# DB pinned to the local service. This is the guardrail against prod RDS.
DB_HOST: db
DB_PORT: "5432"
DB_NAME: vulnerability
DB_USER: vi
DB_PASSWORD: vi_local
DJANGO_SECRET_KEY: local-dev-not-secret
DEBUG: "true"
# Models: read-only pull from S3, cached to the mounted volume (downloads once).
S3_MODELS_BUCKET: ${S3_MODELS_BUCKET:-cfa-vulnerability-index-sandbox-models}
AWS_S3_REGION_NAME: eu-west-1
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
MODEL_CACHE_DIR: /models
# Persist HuggingFace Hub base models on the mounted volume too (matches prod
# Lambda). Without these the ~5.5GB of Hub bases re-download every run.
HF_HOME: /models/hf
TRANSFORMERS_CACHE: /models/hf
# Groq arbitration is part of the real prediction path (Christian's note),
# so the local test includes it. check_groq fails loud if key/model are bad.
GROQ_API_KEY: ${GROQ_API_KEY}
GROQ_MODEL: ${GROQ_MODEL:-qwen/qwen3.6-27b}
volumes:
- ./model_cache:/models
# Local live-edit: source is mounted so code changes apply without a rebuild.
# On the box this runs from the baked image instead (drop these three mounts).
- ./config:/app/config
- ./dashboard:/app/dashboard
- ./fixtures:/app/fixtures
# Lambda tests run against the working tree without baking test-only files
# into the production classifier image.
- ./lambda_function.py:/app/lambda_function.py:ro
- ./inference_client.py:/app/inference_client.py:ro
- ./test_inference_client.py:/app/test_inference_client.py:ro
- ./test_lambda_function.py:/app/test_lambda_function.py:ro
# Full local end-to-end of the split, in one `up`:
# migrate -> schema on the isolated local db
# loaddata -> seed the sample articles from the repo file as
# freshly-ingested, unclassified rows (this is what the
# Lambda ingestion half would leave behind). Re-running
# overwrites by pk, so it doubles as the reset.
# check_groq -> fail loud if the arbitration key/model are dead
# fill_missing_intents -> the classifier half: fills the null intents
# show_results -> print what got classified
command: >
sh -c "python manage.py migrate --noinput &&
python manage.py loaddata fixtures/test_articles.json &&
python manage.py check_groq &&
python manage.py fill_missing_intents &&
python manage.py show_results"