Phần 1 – Foundation | Chương trước: Stateless & Immutable Infrastructure | Chương sau: Factor 1: Codebase

Bốn chương trước đã dựng đủ bối cảnh. Chương này ghép mọi thứ lại thành bức tranh hoàn chỉnh về 12-Factor App: nó từ đâu ra, nó thực chất là gì, cái gì đã lỗi thời, cái gì trường tồn, và đọc nó với thái độ nào.


1. Nguồn gốc lịch sử

2011. Adam Wiggins, đồng sáng lập Heroku, cùng các kỹ sư Heroku công bố The Twelve-Factor App. Bối cảnh quan trọng để hiểu đúng tài liệu gốc:

  • Heroku là PaaS: developer git push, nền tảng tự build và chạy app. Để tự động hóa được ở quy mô hàng trăm nghìn ứng dụng của khách hàng, Heroku cần app của khách tuân theo một “hợp đồng” nhất định.
  • 12-Factor là đúc kết thực nghiệm từ việc quan sát vô số app deploy lên nền tảng: các app trơn tru có chung những tính chất gì, các app trục trặc vi phạm những gì. Nó không phải lý thuyết hàn lâm — nó là field notes.
  • Thời điểm 2011: Docker chưa tồn tại (2013), Kubernetes chưa tồn tại (2014). Điều đáng kinh ngạc là tài liệu viết cho dyno của Heroku lại mô tả gần như chính xác hợp đồng mà container + Kubernetes yêu cầu sau này. Lý do: cả hai cùng giải một bài toán — tự động hóa vòng đời ứng dụng trên hạ tầng tạm bợ — nên hội tụ về cùng một tập nguyên lý.

Năm 2023–2024, cộng đồng (dưới sự bảo trợ của Heroku/Salesforce) đưa 12factor lên GitHub như một dự án mở để hiện đại hóa — bản thân điều này thừa nhận: tài liệu gốc có những điểm cần cập nhật sau hơn một thập kỷ (sẽ nói ở mục 4).


2. 12-Factor thực chất là gì: một hợp đồng, không phải một checklist

Cách đọc sai phổ biến: coi 12 factor là 12 ô cần tick. Cách đọc đúng, như đã xây dựng qua 4 chương:

12-Factor App là bản đặc tả hợp đồng giữa ỨNG DỤNG và NỀN TẢNG TỰ ĐỘNG HÓA. Ứng dụng cam kết có những tính chất nhất định (stateless, disposable, config từ ngoài, log ra stream…); đổi lại, nền tảng — Heroku, Kubernetes, Cloud Run, ECS, bất kỳ — có thể tự động build, deploy, scale, phục hồi và thay thế ứng dụng mà không cần con người can thiệp.

Từ tiền đề “hạ tầng tạm bợ, tự động hóa” (chương 2) và bốn tính chất cloud-native (chương 3), toàn bộ 12 factor được suy ra như sau — đây là bản đồ đọc của Phần 2:

NHÓM 1 — REPRODUCIBLE: "Từ Git dựng lại được mọi thứ"
├── F1  Codebase        : một codebase, nhiều deploy
├── F2  Dependencies    : khai báo tường minh, không dựa vào môi trường
├── F5  Build/Release/Run: ba giai đoạn tách bạch, artifact bất biến
└── F10 Dev/Prod Parity : các môi trường giống nhau tối đa

NHÓM 2 — CONFIGURABLE: "Cùng artifact chạy mọi môi trường"
├── F3  Config          : config nằm trong môi trường, không trong code
└── F4  Backing Services: mọi service ngoài là tài nguyên gắn qua config

NHÓM 3 — DISPOSABLE & SCALABLE: "Process là cattle"
├── F6  Processes       : stateless, share-nothing
├── F7  Port Binding    : app tự phục vụ qua port, không nhúng vào server
├── F8  Concurrency     : scale bằng nhân bản process
└── F9  Disposability   : khởi động nhanh, tắt êm, chết an toàn

NHÓM 4 — OPERABLE: "Vận hành không cần SSH"
├── F11 Logs            : log là event stream ra stdout
└── F12 Admin Processes : tác vụ quản trị chạy như one-off process cùng môi trường

Hệ quả của cách nhìn “hợp đồng”: các factor không độc lập — chúng chống lưng cho nhau. F9 (Disposability) bất khả thi nếu thiếu F6 (Stateless). F5 (Build/Release/Run) vô nghĩa nếu thiếu F3 (Config tách khỏi code). F8 (Concurrency) đứng trên vai F6 + F7. Vi phạm một factor thường kéo sập giá trị của vài factor khác — đó là lý do “tuân thủ 9/12” không cho bạn 75% lợi ích.


3. Mỗi factor giải bài toán gì — bảng tổng hợp trước khi đi sâu

#FactorCâu hỏi nó trả lờiNếu vi phạm
1CodebaseCode nào đang chạy trên production?Không truy vết được; hai môi trường chạy hai “phiên bản sự thật”
2DependenciesApp cần gì để chạy?“Works on my machine”; máy mới không dựng nổi app
3ConfigCùng code chạy nhiều môi trường thế nào?Build riêng cho từng môi trường; secret lộ trong Git
4Backing ServicesĐổi database/cache có phải sửa code?Coupling chặt; không swap được resource; không test được
5Build/Release/RunĐang chạy bản nào, rollback thế nào?Sửa code trên server; không rollback tin cậy
6ProcessesNhân bản process thứ 2 có an toàn?Sticky session, mất data khi restart, không scale được
7Port BindingApp tự chạy hay sống ký sinh trong server?Phụ thuộc app server bên ngoài; khó tự động hóa
8ConcurrencyScale bằng cách nào?Chỉ scale dọc; đến trần phần cứng là hết đường
9DisposabilityGiết process này có an toàn không?Rơi request khi deploy; autoscaling nguy hiểm
10Dev/Prod ParityBug staging có tái hiện đúng production?“Trên staging chạy mà!”; sự cố chỉ xuất hiện production
11LogsDebug 50 instance thế nào?SSH + grep từng máy; mất log khi container chết
12Admin ProcessesMigration/script chạy ở đâu, bằng môi trường nào?Script chạy bằng env khác app → hành vi khác → sự cố

4. Đọc 12-Factor với con mắt 2026 — cái gì lỗi thời, cái gì thiếu

Không thần thánh hóa: tài liệu 2011 có những điểm cần điều chỉnh. Người đọc ở trình độ senior trở lên cần biết rõ:

Những điểm cần đọc lại có phê phán:

  • F3 nguyên bản nói “config lưu trong environment variables” — nguyên tắc config tách khỏi code trường tồn, nhưng cơ chế env var cho secret nay không còn là best practice duy nhất: secret manager (Vault, AWS Secrets Manager), mounted secret file, workload identity thường an toàn hơn. Chương 8 phân tích kỹ.
  • F8 nguyên bản mô tả process type kiểu Heroku (web/worker) — nguyên tắc scale-out trường tồn, nhưng ngày nay đơn vị là container/pod và orchestrator lo việc nhân bản; trong-process concurrency (goroutine!) cũng mạnh hơn nhiều so với thế giới Ruby 2011. Chương 13 cập nhật.
  • F11 “log ra stdout” vẫn đúng, nhưng observability hiện đại cần thêm metrics + traces — 12-Factor nguyên bản im lặng hoàn toàn về chúng.

Những thứ 12-Factor không nói (vì 2011 chưa có bài toán đó) — tài liệu này bổ sung ở Phần 3–4:

  • Health check / readiness / liveness probe (chương 18, 20)
  • Graceful shutdown chi tiết với signal handling (chương 18 — F9 chỉ nói nguyên tắc)
  • Telemetry: metrics, distributed tracing, OpenTelemetry (chương 22)
  • Security: supply chain, image scanning, secret rotation, zero-trust
  • API contract & versioning giữa các service
  • Platform engineering, GitOps, progressive delivery (chương 23)

Một số tài liệu ngành gọi phần mở rộng này là “Beyond the Twelve-Factor App” (Kevin Hoffman, O’Reilly 2016, bản cập nhật 2021 — thêm 3 factor: API First, Telemetry, Security). Tinh thần của tài liệu bạn đang đọc cũng vậy: 12 factor gốc là lõi, hệ sinh thái hiện đại là phần thân.


5. Thái độ đọc đúng: nguyên lý, không phải giáo điều

Ba quy tắc sử dụng xuyên suốt tài liệu, sẽ được nhắc lại bằng ví dụ cụ thể ở từng chương:

Quy tắc 1 — Hiểu bài toán trước, áp dụng giải pháp sau. Mỗi factor giải một bài toán cụ thể. Nếu bạn không có bài toán đó (ví dụ: app desktop không bao giờ có instance thứ hai), factor tương ứng không mang lại giá trị, chỉ mang lại chi phí.

Quy tắc 2 — Chi phí tuân thủ khác nhau, hãy ưu tiên thứ rẻ. Config tách khỏi code, log ra stdout, dependency tường minh, một codebase — gần như miễn phí nếu làm từ đầu, đắt kinh khủng nếu retrofit. Làm ngay ở mọi dự án. Ngược lại, stateless hoàn toàn + hạ tầng đầy đủ có chi phí thật — cân nhắc theo quy mô.

Quy tắc 3 — Vi phạm có ý thức tốt hơn tuân thủ mù quáng. Một kỹ sư giỏi có thể quyết định “app này dùng SQLite trên local disk vì nó là internal tool một instance” — đó là quyết định kiến trúc hợp lệ khi được ghi lại cùng điều kiện đảo chiều (“nếu cần instance thứ hai thì chuyển Postgres”). Vi phạm nguy hiểm là vi phạm vô thức — không biết mình đang đánh đổi gì.


Tóm tắt chương — và bản đồ phần còn lại

  • 12-Factor sinh ra từ kinh nghiệm vận hành PaaS ở quy mô lớn (Heroku, 2011); nó mô tả hợp đồng giữa ứng dụng và nền tảng tự động hóa, và vì thế vẫn đúng với Kubernetes dù ra đời trước Kubernetes 3 năm.
  • 12 factor chia thành 4 nhóm: Reproducible (F1,2,5,10) — Configurable (F3,4) — Disposable & Scalable (F6,7,8,9) — Operable (F11,12). Chúng chống lưng nhau, không phải checklist phẳng.
  • Đọc với con mắt hiện đại: nguyên lý trường tồn, một số cơ chế cụ thể (env var cho secret, process model kiểu Heroku) cần cập nhật; observability/security/API là phần thiếu cần bổ sung.
  • Ba quy tắc: hiểu bài toán trước — ưu tiên factor rẻ — vi phạm có ý thức.

Phần 2 bắt đầu: Factor 1 — Codebase. Mỗi chương factor theo đúng template: Problem Statement → Vì sao tồn tại → Bản chất → Cách áp dụng (Go/Docker/K8s) → Trade-off → Best practices → Anti-patterns → Khi nào không áp dụng.