File size: 5,219 Bytes
344e369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# تبيان الطبي — Deployment Guide

## Prerequisites

- Docker ≥ 24 + Docker Compose v2
- A server with ≥ 4 GB RAM, ≥ 20 GB disk
- Domain name with DNS pointed to your server (for HTTPS)

---

## 1. Environment Setup

Copy and populate the environment file:

```bash
cp .env.example .env
```

Required variables:

```
GROQ_API_KEY=gsk_...
SUPABASE_URL=https://<project>.supabase.co
SUPABASE_KEY=eyJ...
SUPABASE_DB_URL=postgresql+psycopg://...
FRONTEND_URL=https://your-domain.com
NEXTAUTH_SECRET=<32+ random chars>
```

Optional (features degrade gracefully without them):

```
COHERE_API_KEY=...          # reranking (falls back to BM25 only)
GOOGLE_VISION_API_KEY=...   # Vision OCR (falls back to EasyOCR)
GOOGLE_TTS_KEY=...          # Google TTS (falls back to gTTS)
ELEVENLABS_API_KEY=...      # ElevenLabs TTS
SENTRY_DSN=...              # Error monitoring
```

---

## 2. Nginx Configuration

Create `nginx/nginx.conf`:

```nginx
events { worker_connections 1024; }

http {
    upstream backend  { server backend:8000; }
    upstream frontend { server frontend:3000; }

    server {
        listen 80;
        server_name your-domain.com;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        server_name your-domain.com;

        ssl_certificate     /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;

        client_max_body_size 25M;

        location /api/    { proxy_pass http://backend; proxy_set_header Host $host; }
        location /health  { proxy_pass http://backend; }
        location /        { proxy_pass http://frontend; proxy_set_header Host $host; }
    }
}
```

Place TLS certificates in `nginx/certs/` (Let's Encrypt recommended).

---

## 3. Frontend Dockerfile

Create `frontend/Dockerfile`:

```dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
ENV PORT=3000
EXPOSE 3000
CMD ["node", "server.js"]
```

Enable standalone output in `next.config.js`:

```js
module.exports = { output: "standalone" }
```

---

## 4. Deploy

```bash
# Build and start all services
docker compose -f docker-compose.prod.yml up -d --build

# Check logs
docker compose -f docker-compose.prod.yml logs -f backend

# Check health
curl https://your-domain.com/health
```

---

## 5. Supabase Setup

Run once to set up the pgvector extension and required tables:

```sql
-- Enable pgvector
create extension if not exists vector;

-- Documents table for RAG
create table if not exists documents (
  id         bigserial primary key,
  content    text,
  embedding  vector(1024),
  metadata   jsonb
);
create index on documents using ivfflat (embedding vector_cosine_ops) with (lists = 100);

-- match_documents RPC
create or replace function match_documents(
  query_embedding vector(1024),
  match_count     int default 10,
  filter          jsonb default '{}'
)
returns table(id bigint, content text, metadata jsonb, similarity float)
language plpgsql as $$
begin
  return query
  select d.id, d.content, d.metadata,
         1 - (d.embedding <=> query_embedding) as similarity
  from documents d
  order by d.embedding <=> query_embedding
  limit match_count;
end;
$$;

-- Analyses table
create table if not exists analyses (
  id         uuid default gen_random_uuid() primary key,
  session_id text not null,
  findings   jsonb,
  summary    text,
  report     jsonb,
  created_at timestamptz default now()
);
create index on analyses(session_id, created_at desc);
```

---

## 6. PEFT/LoRA Fine-Tuning (Optional)

To improve Arabic medical analysis quality with your own data:

```bash
# 1. Prepare dataset from Supabase analyses
python training/prepare_dataset.py --source supabase --output_dir data/

# 2. Train LoRA adapter (requires GPU with ≥16 GB VRAM)
python training/train_lora.py \
    --model_name core42/jais-13b-chat \
    --data_dir data/ \
    --output_dir checkpoints/tebyan-v1 \
    --num_epochs 3 \
    --load_4bit

# 3. Evaluate
python training/evaluate_model.py \
    --base_model core42/jais-13b-chat \
    --lora_adapter checkpoints/tebyan-v1/lora_adapter \
    --val_data data/val.jsonl \
    --use_llm_judge \
    --groq_key $GROQ_API_KEY
```

Results are written to `eval_results/eval_summary.json`.

---

## 7. Monitoring

The `/api/metrics` endpoint exposes Prometheus-format metrics. Scrape with:

```yaml
# prometheus.yml
scrape_configs:
  - job_name: tebyan
    static_configs:
      - targets: ['your-domain.com']
    metrics_path: /api/metrics
    scheme: https
```

Audit logs are written to the `audit_logs` Docker volume at `logs/audit/audit.jsonl` (rotating, max 50 MB × 10 files).

---

## 8. Updating

```bash
git pull
docker compose -f docker-compose.prod.yml up -d --build --no-deps backend
docker compose -f docker-compose.prod.yml up -d --build --no-deps frontend
```

The `--no-deps` flag updates only the specified service without restarting nginx or volumes.