# Vận hành, triển khai và xử lý sự cố > Loại chính: How-to > Phạm vi: k3s + ArgoCD (production kể từ cutover 2026-08-17) Production (`realvuxbaro.me`) chạy trên k3s, quản lý bởi ArgoCD Application **`medical-chatbot-app`** (ai-service + web + observability) và **`medical-chatbot-data`** (PostgreSQL + Qdrant, tách release để prune/self-heal phía app không bao giờ đụng vào dữ liệu). Cả hai đặt `syncPolicy.automated` với `selfHeal` + `prune` — **mọi merge vào `master` áp thẳng vào production, không có cổng duyệt thủ công.** EC2 Docker Compose (`52.0.158.61`) đã **stop** từ 2026-08-18, không còn nhận deploy tự động và không còn là đường lui sống; xem mục Rollback bên dưới cho cách khởi động lại nếu cần. ## Deploy Hai loại thay đổi đi hai đường khác nhau: **Thay đổi code app** (`apps/ai-service/**`, `apps/web/**`, `packages/**`, `ingestion/data/verified/drug_entities.json`) — merge vào `master` kích hoạt `build-practice-images.yml`: build + push image GHCR gắn tag theo commit SHA, sau đó `.github/scripts/sync_practice_argocd.py` ghi tag mới vào Application `medical-chatbot-app` và gọi sync. Workflow tự xác nhận `readytochat.realvuxbaro.me` đã lên bản mới trước khi báo thành công. `ci.yml` (ruff/pytest/lint/build) chạy độc lập trên cùng push — **CI đỏ không tự động chặn deploy**, hai workflow không phụ thuộc nhau. **Thay đổi chart/config** (`infra/helm/**`) — `helm-chart.yml` lint + render + assert bất biến (Qwen, rerank, TLS, `refute volumeClaimTemplates`...) trên PR. Merge xong, ArgoCD tự phát hiện và sync — không qua CI nào chạy trên production thật, review ở PR là cổng chắn duy nhất. Sau deploy (cả hai loại): 1. xác nhận Application `Synced`/`Healthy` và image tag/chart revision đúng; 2. gửi smoke case qua web, gồm answerable có citation và abstain; 3. quan sát error rate, latency, provider failure và decision distribution; 4. ghi lại thời điểm, SHA/revision và kết quả. ## Rollback **Image bị lỗi (phổ biến nhất):** `gh workflow run rollback-k3s.yml -f target_sha=`. Lấy SHA đó từ lần chạy `build-practice-images.yml` thành công gần nhất trước đó (`gh run list --workflow=build-practice-images.yml`). Workflow tự xác nhận image đã tồn tại trên GHCR, repoint `medical-chatbot-app` (dùng chung `sync_practice_argocd.py` với đường deploy xuôi), chờ tới khi Application thật sự `Synced`/`Healthy` trên đúng tag đó (không chỉ tin lệnh sync đã gọi xong — có race với ArgoCD `selfHeal`, xem comment trong script), rồi mới xác nhận `realvuxbaro.me` sống. Chưa tự động hoá; kích hoạt thủ công qua `workflow_dispatch`, không trigger theo push. **Chart/config bị lỗi:** `git revert` commit gây lỗi trên `master` qua PR bình thường; ArgoCD `selfHeal` tự áp bản revert. Muốn ngay lập tức thay vì chờ chu kỳ poll, sync thủ công qua ArgoCD UI/CLI. **Sự cố nặng ở tầng cluster** (k3s tự nó hỏng, không phải lỗi ở app): Compose EC2 (`i-039fc8f6102467a54`, `52.0.158.61`) đã **stop** (không terminate) ngày 2026-08-18 theo quyết định chỉ dùng 1 EC2 — **không còn là đường lui sống**. Máy vẫn tồn tại (root EBS `DeleteOnTermination=true`, nên terminate mới mất vĩnh viễn), đóng băng ở code `df57e6b` từ trước cutover. Muốn dùng lại làm đường lui khẩn cấp: `aws ec2 start-instances --instance-ids i-039fc8f6102467a54`, chờ container tự khởi động (`docker-compose.prod.yml` không có auto-start service, kiểm tra lại), xác nhận corpus/schema còn tương thích với migration hiện tại của production trước khi trỏ A record — thời gian đứng máy càng lâu, xác suất lệch corpus càng cao. Đây là việc thủ công, không có script/workflow nào làm sẵn. Không có cơ chế nào ở trên tự rollback Qdrant corpus hay database migration. Với corpus, dùng snapshot/migration riêng; không rollback dữ liệu phá huỷ khi chưa có backup. ## Theo dấu request 1. Lấy `trace_id`, `correlation_id`, `otel_trace_id` từ response. 2. Tra `rag_retrieval_trace` để xem query, scope, intent, decision, reason, drug và citations. 3. Kiểm tra Prometheus request/stage duration, decision, provider failure và generation rejection. 4. Nếu OTel bật, tìm trace trong Tempo/Grafana để xác định stage chậm/lỗi. 5. Phân loại nguyên nhân: input/scope, corpus/retrieval, provider/model hoặc grounding. `/metrics` có thể yêu cầu `Authorization: Bearer ` khi `METRICS_TOKEN` được đặt. ## Observability stack Local stack là Prometheus, OpenTelemetry Collector, Tempo và Grafana. OTel mặc định tắt. Observability failure không được làm service dừng trả lời; trace write failure phải xuất hiện trong metric/log. Production monitoring cần readiness và synthetic query vì health không chứng minh citation pipeline hoạt động end-to-end. ## Troubleshooting | Triệu chứng | Kiểm tra đầu tiên | Không nên làm | |---|---|---| | service không ready | datastore, startup log, manifest/model/dimensions | bỏ qua manifest gate | | `provider_unavailable` tăng | region, credential, quota, network, stage trace | báo “Dược thư không có dữ liệu” | | retrieval score thấp | drug/section route, collection và manifest | hạ threshold không qua eval | | grounding rejection tăng | evidence packet, model output, validator | hiển thị raw output | | clarify lặp | history, field thiếu, circuit breaker | tăng loop vô hạn | | citation sai trang | printed-page map, chunk payload, quarantine | thay printed page bằng physical page | Các reason grounding quan trọng gồm `ungrounded_number`, `invalid_citation`, `uncited_claim`, `unsupported_claim` và `incomplete_answer`. Giữ fail-closed và thêm regression test trước khi sửa prompt/parser/validator.