12-factor và build once, deploy many: config nằm ở môi trường Trung cấp
Thời gian đọc ước tính: 3 phút
Trang này trả lời: 12-factor thực sự nói gì về config, và vì sao cùng một image phải đi từ staging lên production.
Ba factor liên quan tới config
Phần tiêu đề “Ba factor liên quan tới config”12-factor có 12 nguyên tắc; ba cái liên quan trực tiếp:
| Factor | Nguyên văn | Hệ quả thực tế |
|---|---|---|
| III. Config | “Store config in the environment” | Config đọc từ env var, không nằm trong code hay image |
| V. Build, release, run | “Strictly separate build and run stages” | Build ra một artifact; release = build kết hợp config của deploy đó |
| X. Dev/prod parity | “Keep development, staging, and production as similar as possible” | Cùng loại backing service, cùng cách nạp config ở mọi môi trường |
Định nghĩa gốc: config là “everything that is likely to vary between deploys”.
Phép thử của 12-factor: codebase có thể open source bất cứ lúc nào mà không lộ credential không?
Hai điểm hay bị hiểu sai
Phần tiêu đề “Hai điểm hay bị hiểu sai”- 12-factor không coi config nội bộ (route, wiring DI) là config. Thứ không đổi theo deploy thì để trong code.
- 12-factor khuyên env var là “granular controls”, không gom thành nhóm “environments” như
config.production.json.
Code kiểu if (NODE_ENV === 'production') timeout = 5000 chính là gom nhóm trá hình. Ví dụ bad/good ở Lỗi hay gặp.
Factor XI: log không phải config
Phần tiêu đề “Factor XI: log không phải config”App ghi log ra stdout (“writes its event stream, unbuffered, to stdout”) và để môi trường định tuyến.
Hệ quả: đường dẫn file log không phải là config app cần biết. Không cần LOG_FILE_PATH.
Build once, deploy many
Phần tiêu đề “Build once, deploy many”push imageCI build đúng một lần cho mỗi commit và đẩy image có tag theo git SHA. Image không chứa URL, password hay tên môi trường.
Hệ quả của factor V: image không biết nó đang chạy ở đâu. Không có npm run build:prod, không bake .env.production vào image.
| Lý do | Giải thích |
|---|---|
| Test đúng thứ sẽ chạy | Staging test đúng byte sẽ lên production. Build lại cho production là chạy một artifact chưa từng được test. |
| Rollback rẻ | Rollback là chạy lại digest cũ với config hiện tại, không cần build. |
| Image không chứa bí mật | Image có password bên trong thì ai pull được image là đọc được password. |
Docker docs nói thẳng: build argument và env var “are inappropriate for passing secrets to your build” vì “they persist in the final image”. Cần secret lúc build (vd token npm private) thì dùng secret mount.
Ngoại lệ thường gặp: frontend build-time variable (bundler thay giá trị vào JS lúc build). Với backend, không có lý do chính đáng để làm vậy.
Promote theo digest
Phần tiêu đề “Promote theo digest”# staging và production dùng CÙNG digest, chỉ khác ConfigMap/Secretimage: registry.example.com/payment-api@sha256:...- Tag (
:latest,:1.4.2) có thể bị ghi đè; digest thì không. - Pipeline promote = đổi môi trường đích, không chạy lại
docker build.
Tiếp theo: Parse và validate env.