Chương 46. CI/CD

Ở chương trước, ta nói về Docker và container.

Container giúp đóng gói app thành artifact rõ ràng hơn.

Chương này nói về cách đưa artifact đó từ code lên production một cách có kiểm soát:

CI/CD.

CI là Continuous Integration.

CD có thể là Continuous Delivery hoặc Continuous Deployment.

Không cần bị kẹt vào thuật ngữ.

Hãy hiểu thực dụng:

> CI/CD là đường ống tự động giúp code được build, test, đóng gói, deploy và rollback theo quy trình lặp lại được.

Thông điệp chính của chương:

> Deploy tay dễ lỗi vì con người dễ quên bước, làm khác nhau mỗi lần, và khó truy vết. CI/CD biến deploy thành quy trình rõ ràng, có kiểm tra, có artifact, có log, có rollback plan.

---

46.1. Ví dụ dễ hiểu: nấu ăn theo công thức hay nấu bằng trí nhớ

Bạn có thể nấu một món bằng trí nhớ.

Hôm nay nhớ bỏ muối.

Ngày mai quên.

Hôm nay nấu 20 phút.

Ngày mai nấu 35 phút.

Hôm nay dùng đúng nguyên liệu.

Ngày mai thiếu một món nhưng vẫn cố làm.

Kết quả mỗi lần khác nhau.

Deploy tay cũng giống vậy.

SSH vào server.
git pull.
pip install.
npm build.
restart service.
chạy migration.
clear cache.
kiểm tra log.

Một hôm bạn quên migration.

Một hôm bạn restart nhầm service.

Một hôm bạn deploy từ branch sai.

CI/CD giống một dây chuyền có công thức rõ.

Mỗi lần code đi qua cùng một đường.

---

46.2. Vì sao deploy tay dễ lỗi?

Deploy tay có nhiều rủi ro:

  • Làm thiếu bước.
  • Làm sai thứ tự.
  • Chạy nhầm branch.
  • Chạy nhầm server.
  • Quên env var.
  • Quên build frontend.
  • Quên migration.
  • Restart sai process.
  • Không biết version nào đang chạy.
  • Không có log deploy rõ.
  • Không rollback nhanh được.

Deploy tay có thể ổn lúc app nhỏ và một người làm.

Nhưng khi production có dữ liệu thật, user thật, nhiều service, nhiều worker:

Deploy phải lặp lại được và truy vết được.

Không nên phụ thuộc vào trí nhớ.

---

46.3. CI là gì?

CI là quá trình kiểm tra code thường xuyên khi code được push hoặc mở pull request.

CI thường làm:

Checkout code
Install dependencies
Run lint
Run tests
Build app
Build Docker image nếu cần

Mục tiêu:

Phát hiện lỗi sớm trước khi merge/deploy.

Ví dụ:

Developer push code.
CI chạy test.
Test fail.
Không merge.

CI là hàng rào đầu tiên.

Nó không bắt được mọi lỗi production.

Nhưng nó bắt được nhiều lỗi cơ bản trước khi vào hệ thống thật.

---

46.4. CD là gì?

CD có hai cách hiểu.

Continuous Delivery:

Code luôn ở trạng thái có thể deploy.
Deploy production có thể cần người bấm approve.

Continuous Deployment:

Code qua test là tự deploy production.

Không phải team nào cũng cần tự deploy production hoàn toàn.

Với nhiều sản phẩm, cách thực dụng là:

Tự động deploy staging.
Production cần approval.

Điểm quan trọng:

> CD không chỉ là tự động. CD là khả năng đưa code lên môi trường thật một cách đáng tin, lặp lại được.

---

46.5. Pipeline là gì?

Pipeline là chuỗi bước tự động.

Ví dụ:

1. Checkout code.
2. Install dependencies.
3. Run lint.
4. Run unit tests.
5. Run integration tests.
6. Build frontend.
7. Build Docker image.
8. Scan image.
9. Push image to registry.
10. Deploy staging.
11. Run smoke test.
12. Approve production.
13. Deploy production.
14. Monitor health.

Không phải app nào cũng cần đủ mọi bước từ đầu.

Nhưng tư duy là:

Code đi qua một đường rõ ràng.

Mỗi bước fail thì pipeline dừng.

Không để lỗi trôi xuống production nếu có thể bắt sớm.

---

46.6. Build là gì?

Build là biến source code thành artifact có thể chạy/deploy.

Artifact có thể là:

  • Docker image.
  • Java JAR.
  • Node build output.
  • Frontend static assets.
  • Python package.
  • Binary.

Với Docker, artifact thường là:

Docker image tag cụ thể.

Ví dụ:

synvia-api:2026-05-12-a1b2c3

Điểm quan trọng:

> Thứ được deploy nên là artifact đã build/test, không phải mỗi lần production tự build tùy hứng.

Build một lần, deploy cùng artifact qua staging rồi production sẽ đáng tin hơn.

---

46.7. Test trong pipeline

Test trong CI/CD có nhiều lớp:

Unit test:

Test logic nhỏ.
Nhanh.

Integration test:

Test app với database/queue/service giả hoặc thật.

End-to-end test:

Test flow gần giống user thật.

Smoke test:

Sau deploy, kiểm tra app sống và flow cơ bản chạy.

Không cần mọi thứ đều là E2E test.

Test càng gần user thật càng hữu ích nhưng thường chậm và dễ flake hơn.

Pipeline tốt cân bằng:

Nhiều test nhanh.
Một số test tích hợp quan trọng.
Một ít smoke/E2E cho flow sống còn.

---

46.8. Lint và format

Lint/format không phải phần quan trọng nhất của architecture.

Nhưng chúng giúp giảm lỗi cơ bản và tranh luận vô ích.

CI có thể chạy:

  • Formatter check.
  • Linter.
  • Type check.
  • Static analysis.

Ví dụ:

TypeScript type check.
Python ruff/mypy nếu dùng.
Go test/vet.
Java compile/checkstyle.

Mục tiêu:

Để máy bắt lỗi máy bắt được.
Con người tập trung review logic.

---

46.9. Artifact phải truy vết được

Khi production lỗi, câu hỏi đầu tiên:

Version nào đang chạy?
Deploy lúc nào?
Ai approve?
Commit nào?
Image tag nào?
Migration nào chạy?

Nếu không trả lời được, incident khó xử lý.

Artifact nên gắn với:

  • Git commit.
  • Build number.
  • Image tag.
  • Release version.
  • Timestamp.

Ví dụ:

synvia-api:git-a1b2c3-build-456

Log deploy nên ghi:

Deploy version X to staging.
Deploy version X to production.

Không deploy bằng latest mơ hồ.

---

46.10. Environment: dev, staging, production

Pipeline thường đi qua nhiều môi trường.

Dev/local:

Developer làm việc.

Staging:

Giống production hơn.
Test deploy, migration, integration.

Production:

Người dùng thật, dữ liệu thật.

Artifact nên giống nhau giữa staging và production.

Config khác nhau:

  • Database URL.
  • Secret.
  • Domain.
  • Provider sandbox/live.
  • Scale.

Không nên build một image riêng tùy tiện cho production nếu staging test image khác.

Tốt hơn:

Cùng image.
Khác config runtime.

---

46.11. Secrets trong CI/CD

Pipeline thường cần secret:

  • Registry credential.
  • Cloud deploy credential.
  • SSH key.
  • API token.
  • Signing key.
  • Environment secret.

Secret trong CI/CD rất nhạy cảm.

Không nên:

  • In secret ra log.
  • Lưu secret trong repo.
  • Cho mọi branch/fork truy cập secret production.
  • Dùng một key quá rộng cho mọi việc.

Nên:

  • Dùng secret store của CI platform.
  • Giới hạn secret theo environment.
  • Dùng short-lived credential nếu có.
  • Dùng approval cho production.
  • Rotate key.
  • Audit ai dùng secret.

CI/CD là đường vào production.

Bảo mật pipeline là bảo mật production.

---

46.12. Deploy staging

Staging deploy nên tự động hơn production.

Ví dụ:

Merge vào main
-> build image
-> deploy staging
-> run smoke test

Staging giúp bắt lỗi:

  • Env var thiếu.
  • Migration lỗi.
  • Docker image lỗi.
  • Static asset lỗi.
  • Integration config lỗi.
  • Worker không start.
  • Queue connection lỗi.

Staging không giống production hoàn toàn.

Nhưng nó là nơi rất tốt để test đường deploy.

---

46.13. Smoke test là gì?

Smoke test là kiểm tra nhanh sau deploy để biết hệ thống cơ bản còn sống.

Ví dụ:

GET /health
Login test account.
Call basic API.
Create test job nhỏ.
Check worker xử lý được.
Check frontend asset load được.

Smoke test không cần phủ toàn bộ app.

Nó kiểm tra:

Deploy này có làm hệ thống chết ngay không?

Với AI Judge, smoke test có thể:

API health ok.
DB connection ok.
Queue connection ok.
Worker heartbeat ok.
Create dummy grading job với fake AI provider ở staging.

---

46.14. Production approval

Không phải pipeline nào cũng nên tự đẩy production ngay.

Production approval hữu ích khi:

  • Team nhỏ.
  • Sản phẩm có dữ liệu nhạy cảm.
  • Deploy cần quan sát.
  • Có migration.
  • Có thay đổi hạ tầng.
  • Chưa có test đủ mạnh.

Approval không nên là nghi thức hình thức.

Người approve nên nhìn:

  • Build xanh.
  • Test xanh.
  • Staging ổn.
  • Migration có an toàn không.
  • Release note thay đổi gì.
  • Có rollback plan không.

CI/CD giúp tự động hóa.

Nhưng vẫn có thể giữ điểm kiểm soát hợp lý.

---

46.15. Rolling deploy

Rolling deploy là deploy dần từng instance.

Ví dụ có 4 API instances:

api-1 -> version mới -> healthy
api-2 -> version mới -> healthy
api-3 -> version mới -> healthy
api-4 -> version mới -> healthy

Trong lúc đó, load balancer chỉ gửi traffic đến instance healthy.

Ưu điểm:

  • Ít downtime.
  • Không tắt toàn bộ app cùng lúc.
  • Có thể dừng nếu instance mới lỗi.

Cần:

  • Health check đúng.
  • Graceful shutdown.
  • App stateless.
  • Code cũ/mới tương thích.
  • Migration an toàn.

Rolling deploy không tự giải quyết database schema breaking change.

---

46.16. Blue-green deploy

Blue-green deploy dùng hai môi trường:

Blue: production hiện tại.
Green: version mới.

Deploy version mới vào Green.

Test Green.

Chuyển traffic sang Green.

Nếu lỗi, chuyển lại Blue.

Ưu điểm:

  • Rollback traffic nhanh.
  • Green được chuẩn bị trước.
  • Giảm downtime.

Nhược điểm:

  • Tốn tài nguyên.
  • Database migration vẫn khó.
  • Background jobs/state cần cẩn thận.

Blue-green rất tốt khi hạ tầng hỗ trợ.

Nhưng đừng quên dữ liệu chung phía sau.

Nếu Green đã ghi dữ liệu format mới, Blue có đọc được không?

---

46.17. Canary deploy

Canary deploy là deploy cho một phần nhỏ traffic trước.

Ví dụ:

1% traffic -> version mới
99% traffic -> version cũ

Nếu ổn:

10%
50%
100%

Canary giúp phát hiện lỗi thật với ảnh hưởng nhỏ hơn.

Cần:

  • Metrics tốt.
  • Error tracking.
  • So sánh version cũ/mới.
  • Khả năng route traffic.
  • Rollback nhanh.

Canary không có observability thì rất yếu.

Bạn phải nhìn được version mới có lỗi hơn không.

---

46.18. Feature flag và deploy

Feature flag tách:

Deploy code

khỏi:

Bật tính năng

Ví dụ:

Deploy new_grading_pipeline code.
Flag vẫn off.
Bật cho internal users.
Bật cho 5% tenant.
Bật toàn bộ nếu ổn.

Nếu lỗi:

Tắt flag.

Feature flag rất hữu ích cho:

  • Tính năng rủi ro.
  • Migration hành vi.
  • Rollout dần.
  • A/B testing.
  • Kill switch.

Nhưng flag cũ cần dọn.

Nếu không code sẽ đầy nhánh logic.

---

46.19. Rollback là gì?

Rollback là quay lại version trước khi deploy lỗi.

Ví dụ:

Deploy version 46.
Error rate tăng.
Rollback về version 45.

Rollback tốt cần biết:

  • Version trước là gì.
  • Artifact còn không.
  • Config có đổi không.
  • Migration có tương thích không.
  • Job payload có đổi không.
  • Cache có cần clear không.
  • Frontend asset cũ còn không.

Rollback không chỉ là:

git revert.

Rollback production là đưa hệ thống về trạng thái chạy được.

---

46.20. Roll forward

Đôi khi rollback khó.

Ví dụ migration đã đổi dữ liệu.

Lúc này cách nhanh hơn có thể là roll forward:

Deploy hotfix sửa lỗi trên version mới.

Rollback hay roll forward tùy tình huống.

Câu hỏi khi incident:

  • Lỗi có nghiêm trọng không?
  • Rollback có an toàn không?
  • Hotfix có nhanh hơn không?
  • Dữ liệu đã bị thay đổi chưa?
  • Có thể tắt feature flag không?

Feature flag tốt giúp tránh phải rollback toàn bộ.

---

46.21. Database migration trong lúc deploy

Database migration là phần khó nhất của deploy.

Vì code có thể rollback nhanh.

Dữ liệu/schema thì không luôn rollback dễ.

Ví dụ nguy hiểm:

Deploy code mới cần cột new_score.
Migration rename cột score -> new_score.
Trong lúc rolling deploy, code cũ vẫn chạy và tìm cột score.

Kết quả:

Code cũ lỗi.

Vì rolling deploy có thời điểm code cũ và mới cùng tồn tại.

Migration phải tương thích với giai đoạn đó.

---

46.22. Expand and contract

Expand and contract là pattern migration an toàn.

Ví dụ muốn đổi score sang final_score.

Bước 1: Expand.

Thêm cột final_score nullable.
Code vẫn đọc score.

Bước 2: Dual write hoặc backfill.

Code ghi cả score và final_score.
Backfill dữ liệu cũ.

Bước 3: Switch read.

Code đọc final_score.

Bước 4: Contract.

Sau khi chắc chắn, xóa score.

Không phải migration nào cũng cần phức tạp thế.

Nhưng với thay đổi breaking trên bảng quan trọng, đây là tư duy rất hữu ích.

---

46.23. Backfill

Backfill là điền dữ liệu cũ cho field mới hoặc cấu trúc mới.

Ví dụ:

Thêm cột grading_cost_usd.
Tính lại từ usage records cũ.

Backfill có thể nặng.

Không nên luôn chạy backfill lớn trong migration transaction.

Có thể cần:

  • Chạy theo batch.
  • Chạy nền.
  • Giới hạn tốc độ.
  • Monitor progress.
  • Có thể resume.
  • Không lock bảng quá lâu.

Production database lớn không thích thao tác một phát trên hàng triệu row.

---

46.24. Migration nên chạy ở đâu?

Một số cách:

1. Pipeline chạy migration trước deploy.

2. Pipeline deploy code rồi chạy migration.

3. Một migration job riêng.

4. App tự chạy migration khi start.

Cách 4 dễ nhưng nguy hiểm nếu nhiều instances cùng chạy.

Thực dụng hơn:

Migration là bước có kiểm soát trong pipeline.

Với migration nhỏ, có thể tự động.

Với migration lớn, cần approval và plan riêng.

Điểm quan trọng:

> Đừng để mọi container production tự đua nhau chạy migration nếu không có lock và quy trình rõ.

---

46.25. Worker và deploy

Deploy không chỉ có web app.

Còn worker.

Worker có vấn đề riêng:

  • Worker cũ đang xử lý job.
  • Job payload format thay đổi.
  • Queue còn job cũ.
  • Worker mới đọc job cũ được không?
  • Worker cũ ghi result theo schema cũ.
  • Retry job sau deploy dùng code mới.

Ví dụ AI Judge:

GradingJob payload version 1:
  submission_id

Payload version 2:
  submission_id
  rubric_version
  model_config

Worker mới nên đọc được payload cũ, hoặc migration job phải nâng version payload.

Không nghĩ đến worker là deploy dễ vỡ.

---

46.26. Versioned job payload

Job payload nên có version nếu có khả năng thay đổi.

Ví dụ:

{
  "version": 2,
  "submission_id": "sub_123",
  "rubric_version": "rubric_7",
  "model_config_id": "model_config_4"
}

Worker xử lý:

Nếu version 1: dùng logic cũ.
Nếu version 2: dùng logic mới.

Không phải mọi job cần version từ đầu.

Nhưng job quan trọng, sống lâu trong queue, retry nhiều lần, nên nghĩ đến compatibility.

---

46.27. Frontend deploy và cache

Frontend deploy có quan hệ với CDN/cache.

Pattern tốt:

Build asset có hash.
Upload asset mới.
HTML trỏ asset mới.
Giữ asset cũ một thời gian.

Nếu xóa asset cũ ngay, user đang mở tab cũ có thể gặp lỗi.

Nếu cache HTML quá lâu, user không thấy version mới.

CI/CD frontend nên biết:

  • Asset upload trước.
  • HTML deploy sau.
  • Cache headers đúng.
  • Rollback có asset cũ.

Deploy frontend cũng có production complexity.

---

46.28. Config change cũng là deploy

Không chỉ code mới là deploy.

Thay config cũng có thể làm hệ thống lỗi:

  • Env var.
  • Feature flag.
  • Rate limit.
  • Timeout.
  • CORS origin.
  • WAF rule.
  • Worker concurrency.
  • AI model config.
  • Secret rotation.

Config change nên có:

  • Review.
  • Audit.
  • Rollback.
  • Staging test nếu có thể.

Đừng xem config production là thứ sửa tay tùy hứng.

Nhiều incident đến từ config, không phải code.

---

46.29. Infrastructure as Code

Infrastructure as Code, viết tắt IaC, là quản lý hạ tầng bằng code.

Ví dụ:

  • Terraform.
  • Pulumi.
  • CloudFormation.
  • CDK.

IaC giúp:

  • Review thay đổi hạ tầng.
  • Lưu lịch sử.
  • Tạo môi trường lặp lại được.
  • Giảm click tay trong cloud console.
  • Dễ rollback/thấy khác biệt hơn.

Không phải app nhỏ cần IaC toàn bộ từ ngày đầu.

Nhưng khi hạ tầng lớn hơn, click tay trong console sẽ khó kiểm soát.

CI/CD có thể chạy plan/apply với approval.

---

46.30. Deployment log và release note

Mỗi deploy nên có log:

Version nào?
Commit nào?
Ai trigger?
Deploy môi trường nào?
Thời gian nào?
Kết quả?
Migration nào?

Release note ngắn giúp team biết:

  • Tính năng gì mới.
  • Bug gì sửa.
  • Có migration không.
  • Có flag mới không.
  • Có rủi ro cần theo dõi không.

Khi user báo lỗi:

Lỗi bắt đầu từ khi nào?
Có deploy nào gần đó không?

Deployment log giúp trả lời nhanh.

---

46.31. Monitoring sau deploy

Deploy xong chưa phải hết việc.

Cần nhìn:

  • Error rate.
  • Latency.
  • 5xx.
  • Queue backlog.
  • Worker failure.
  • Database CPU/connection.
  • External API timeout.
  • Cost spike.
  • Business metric quan trọng.

Ví dụ AI Judge:

Sau deploy new grading pipeline:
  grading_failed tăng không?
  retry tăng không?
  avg grading time tăng không?
  AI cost tăng không?

CI/CD nên nối với observability.

Deploy mà không nhìn hệ thống sau đó là hơi liều.

---

46.32. Automated rollback có nên không?

Một số platform hỗ trợ tự rollback nếu health check fail.

Điều này hữu ích với lỗi rõ:

App không start.
Health check fail.
5xx tăng mạnh.

Nhưng automated rollback cũng cần cẩn thận.

Nếu lỗi do migration không tương thích, rollback code có thể làm tệ hơn.

Nếu metric báo sai, rollback không cần thiết.

Thực dụng:

Tự rollback cho lỗi start/health rõ.
Con người quyết định cho lỗi dữ liệu/nghiệp vụ phức tạp.

---

46.33. Branching và release

Có nhiều workflow:

  • Trunk-based development.
  • GitFlow.
  • Release branches.
  • Feature branches.

Không cần tranh luận tôn giáo.

Điểm quan trọng:

  • Code được merge thường xuyên.
  • CI chạy trên PR/main.
  • Main luôn tương đối deployable.
  • Release process rõ.
  • Hotfix có đường đi nhanh.

Team nhỏ thường hợp với:

Pull request -> CI -> merge main -> deploy staging -> approve production.

Feature flag giúp main vẫn deploy được dù tính năng chưa bật.

---

46.34. Preview environment

Preview environment là môi trường tạm cho một PR/branch.

Ví dụ:

PR #123 có URL riêng:
https://pr-123.preview.example.com

Rất hữu ích cho:

  • Review UI.
  • Test flow.
  • Product/design xem trước.
  • QA.

Nhưng preview environment cần quản lý:

  • Chi phí.
  • Dữ liệu test.
  • Secret.
  • Cleanup sau PR.
  • Không dùng production secret/dữ liệu nhạy cảm.

Không bắt buộc, nhưng rất tiện với frontend/product nhiều.

---

46.35. CI/CD cho app nhỏ

App nhỏ không cần pipeline khổng lồ.

Một pipeline tốt ban đầu:

On pull request:
  run tests/lint

On merge main:
  build image
  push image
  deploy staging
  smoke test

Manual approval:
  deploy production

Đủ để giảm nhiều lỗi deploy tay.

Sau đó thêm:

  • Security scan.
  • E2E test.
  • Canary.
  • IaC.
  • Automated rollback.

Đi từng bước.

CI/CD tốt lên theo rủi ro và quy mô.

---

46.36. CI/CD cho microservices

Microservices thêm độ phức tạp.

Cần nghĩ:

  • Service nào thay đổi?
  • Deploy thứ tự nào?
  • API contract có tương thích không?
  • Consumer có đọc được response mới không?
  • Event schema có đổi không?
  • Database mỗi service migration thế nào?
  • Rollback một service có ảnh hưởng service khác không?

CI/CD microservices cần:

  • Contract tests nếu cần.
  • Versioned API/event.
  • Independent deploy.
  • Observability theo service.
  • Backward compatibility.

Không thể chỉ copy pipeline monolith rồi hy vọng ổn.

---

46.37. Contract test

Contract test kiểm tra hợp đồng giữa service/client.

Ví dụ:

Submission Service hứa response có field status.
Teacher Dashboard phụ thuộc field đó.

Nếu service đổi field làm client vỡ, contract test nên phát hiện.

Contract test hữu ích khi:

  • Nhiều service.
  • Nhiều team.
  • API public/partner.
  • Event schema quan trọng.

Không phải mọi app nhỏ cần.

Nhưng càng phân tán, contract càng quan trọng.

---

46.38. AI Judge: pipeline đơn giản

AI Judge giai đoạn đầu có thể có pipeline:

Pull request:
  lint
  unit tests
  backend tests
  frontend build

Merge main:
  build api/worker image
  push image registry
  deploy staging
  run smoke test

Production:
  manual approval
  run safe migration step
  deploy api
  deploy worker
  monitor queue/error/cost

Nếu worker và API cùng image:

Một image.
Hai command khác nhau.

Deploy vẫn cần quan sát cả API và worker.

---

46.39. AI Judge: migration cần đặc biệt cẩn thận

Các bảng quan trọng:

Submission
GradingJob
GradingResult
Rubric
User/Course

Migration trên các bảng này có thể ảnh hưởng trực tiếp đến:

  • Nộp bài.
  • Chấm bài.
  • Hiển thị điểm.
  • Quyền teacher/student.

Ví dụ thêm rubric_version_id vào grading job.

Làm an toàn:

1. Add column nullable.
2. Deploy worker biết xử lý cả null và non-null.
3. Backfill jobs/results nếu cần.
4. Deploy code bắt đầu ghi field mới.
5. Sau khi ổn, mới enforce not null.

Đừng đổi schema theo kiểu làm code cũ chết trong rolling deploy.

---

46.40. AI Judge: deploy worker không giống deploy API

API request thường ngắn.

Worker job có thể dài:

Chấm bài 90 giây.
Xử lý file vài phút.
Export report lâu.

Khi deploy worker:

  • Có cho job đang chạy hoàn tất không?
  • Worker có graceful shutdown không?
  • Job ack khi nào?
  • Retry có tạo trùng không?
  • Payload cũ/new compatible không?
  • Worker concurrency có thay đổi không?

Nếu kill worker giữa job mà job đã ack, job có thể mất.

Nếu retry không idempotent, có thể ghi kết quả trùng.

Deploy worker cần hiểu queue semantics.

---

46.41. AI Judge: canary grading pipeline

Nếu đổi prompt/model/chấm bài pipeline, không nên bật toàn bộ ngay.

Có thể:

Deploy code mới.
Flag new_grading_pipeline = off.
Bật cho internal/test course.
Bật cho 5% assignment.
So sánh error/time/cost/teacher override.
Tăng dần.

Metrics cần theo dõi:

  • Grading success rate.
  • Timeout rate.
  • Average latency.
  • Token/cost.
  • Retry count.
  • Teacher override rate.
  • Student appeal/regrade request.

Đây là canary ở mức sản phẩm/nghiệp vụ, không chỉ traffic.

---

46.42. Những lỗi CI/CD phổ biến

Lỗi 1:

Pipeline xanh nhưng không build đúng thứ production chạy.

Lỗi 2:

Deploy bằng latest nên không truy vết được version.

Lỗi 3:

Secret production có thể truy cập từ PR không tin cậy.

Lỗi 4:

Migration breaking chạy trong rolling deploy.

Lỗi 5:

Worker job payload đổi nhưng không backward-compatible.

Lỗi 6:

Không có smoke test sau deploy.

Lỗi 7:

Không có rollback plan.

Lỗi 8:

Deploy xong không theo dõi metrics.

Lỗi 9:

Config production sửa tay không audit.

Lỗi 10:

Pipeline quá chậm nên developer tìm cách né.

---

46.43. Checklist CI/CD

Hỏi:

  • Pipeline chạy khi nào?
  • Test nào bắt buộc trước merge?
  • Artifact deploy là gì?
  • Artifact có tag/commit rõ không?
  • Staging có deploy tự động không?
  • Production có approval không?
  • Secret production được bảo vệ thế nào?
  • Migration chạy ở bước nào?
  • Migration có backward-compatible không?
  • Worker/job payload có tương thích không?
  • Frontend asset/cache deploy thế nào?
  • Rollback version trước là gì?
  • Config change có audit không?
  • Smoke test sau deploy có gì?
  • Deploy xong theo dõi metric nào?
  • Ai chịu trách nhiệm khi deploy lỗi?

Checklist này không làm pipeline thay bạn suy nghĩ.

Nó giúp không quên thứ quan trọng.

---

46.44. Bảng chọn nhanh

| Nhu cầu | Cách nghĩ thường hợp | |---|---| | Giảm lỗi deploy tay | Pipeline build/test/deploy | | Biết version production | Artifact tag theo commit/build | | Test trước production | Auto deploy staging + smoke test | | Production nhạy cảm | Manual approval | | Ít downtime | Rolling/blue-green deploy | | Rollout rủi ro thấp | Canary + metrics | | Bật/tắt tính năng nhanh | Feature flag | | Migration schema lớn | Expand/contract + backfill theo batch | | Worker job lâu | Graceful shutdown + idempotency + payload version | | Nhiều service | Contract/backward compatibility |

---

46.45. Tóm tắt bằng AI Judge

Với AI Judge, CI/CD tốt nên giúp:

Build API/worker image rõ version.
Run test trước merge.
Deploy staging tự động.
Smoke test API/DB/queue/worker.
Approve production có kiểm soát.
Run migration an toàn.
Deploy API và worker cẩn thận.
Theo dõi queue, job fail, AI timeout, cost sau deploy.
Rollback hoặc tắt feature flag khi có lỗi.

Điểm đặc biệt cần chú ý:

Worker job có thể đang chạy lúc deploy.
Job payload có thể sống lâu trong queue.
AI pipeline mới nên rollout bằng flag/canary.
Migration bảng Submission/GradingJob/GradingResult phải tương thích.

CI/CD không làm kiến trúc đúng thay bạn.

Nhưng nó giúp việc đưa kiến trúc đó lên production ít phụ thuộc vào may mắn hơn.

---

46.46. Kết luận của chương

CI/CD là một phần quan trọng của hệ thống production.

Nó không chỉ là "automation cho tiện".

Nó là cách giảm lỗi người, tăng khả năng truy vết, kiểm tra trước khi deploy, đưa artifact rõ ràng qua các môi trường, và chuẩn bị rollback khi có sự cố.

Thông điệp cần nhớ:

> Deploy tốt là deploy lặp lại được, quan sát được, rollback được, và không làm dữ liệu/schema/job bị vỡ trong lúc version cũ mới cùng tồn tại.

Ở chương tiếp theo, ta sẽ nói về Kubernetes: Kubernetes giải quyết orchestration như thế nào, pod/service/deployment là gì theo cách dễ hiểu, khi nào Kubernetes đáng dùng, khi nào nó quá nặng, và vì sao Kubernetes không thay thế hiểu biết về app.