12-Factor App – Dependencies: Khai báo đầy đủ và cô lập mọi thư viện phụ thuộc
Một trong những nguyên nhân phổ biến nhất khiến ứng dụng chạy được trên máy lập trình viên nhưng thất bại khi triển khai là quản lý dependency không đúng cách.
Đó cũng là lý do nguyên tắc thứ hai của 12-Factor App nhấn mạnh:
Nguyên tắc này giúp ứng dụng có thể được triển khai lặp lại (repeatable deployment), giảm lỗi do khác biệt môi trường và là nền tảng của CI/CD hiện đại.
Dependency là gì?
Dependency là các thư viện, framework hoặc package mà ứng dụng cần để hoạt động.
Ví dụ:
Nếu thiếu một dependency hoặc dùng sai phiên bản, ứng dụng có thể không build được hoặc hoạt động không chính xác.
Luôn khai báo Dependency một cách tường minh
12-Factor App khuyến nghị không bao giờ giả định rằng máy chủ đã cài sẵn các thư viện cần thiết.
Thay vào đó, mọi dependency phải được khai báo trong các file manifest.
Ví dụ:
Python
requirements.txtrequests
scrapy
nose
netaddr==0.7.19
ncclient>=0.6.1
Trong ví dụ trên:
Sau đó chỉ cần chạy:
pip install -r requirements.txt
là toàn bộ môi trường sẽ được thiết lập tự động.
Mỗi nền tảng đều có Package Manager riêng
Hầu hết các ngôn ngữ lập trình đều có công cụ quản lý dependency:
Python
Node.js
Java
.NET
Các công cụ này giúp tự động tải đúng thư viện và đúng phiên bản, thay vì cài đặt thủ công trên từng máy.
Vì sao phải cô lập Dependency?
Khai báo dependency thôi là chưa đủ.
12-Factor App còn yêu cầu isolate dependencies – cô lập môi trường của từng ứng dụng.
Hãy tưởng tượng một máy chủ chạy hai ứng dụng Python:
Nếu cả hai cùng dùng thư viện cài đặt toàn cục (system-wide), việc nâng cấp cho ứng dụng B có thể làm ứng dụng A ngừng hoạt động.
Đây là nguyên nhân của rất nhiều sự cố trong môi trường Production.
Virtual Environment trong Python
Để tránh xung đột, Python sử dụng Virtualenv.
Ví dụ:
virtualenv myproject
Kích hoạt môi trường:
source myproject/bin/activate
Từ thời điểm đó:
Đây là một trong những thực hành quan trọng của phát triển Python hiện đại.
Container còn tiến thêm một bước
Ngày nay, Docker giúp cô lập dependency ở mức cao hơn.
Mỗi container chứa:
Nhờ đó, ứng dụng luôn chạy trong đúng môi trường đã được kiểm thử, bất kể máy chủ bên dưới là Linux, Windows hay Cloud.
Đây cũng là lý do Docker và Kubernetes trở thành nền tảng của các kiến trúc Cloud-Native.
Lợi ích đối với CI/CD
Khi dependency được khai báo đầy đủ và cô lập, pipeline CI/CD chỉ cần:
pip install -r requirements.txt
hoặc
npm install
hay
mvn install
là có thể tự động dựng đúng môi trường để:
Không còn phụ thuộc vào việc máy chủ đã cài gì trước đó.
Điều này giúp quá trình triển khai có thể lặp lại nhiều lần với kết quả nhất quán (repeatable deployment), giảm đáng kể lỗi do khác biệt môi trường.
Best Practices
Một số nguyên tắc nên áp dụng trong các dự án DevOps hiện đại:
Kết luận
Nguyên tắc Dependencies của 12-Factor App nghe có vẻ đơn giản nhưng là nền tảng cho khả năng triển khai ổn định và tự động hóa.
Một ứng dụng hiện đại nên:
Khi tuân thủ nguyên tắc này, các nhóm DevOps, Cloud Engineer và Platform Engineer có thể xây dựng các pipeline CI/CD đáng tin cậy, giảm lỗi do khác biệt môi trường và triển khai ứng dụng nhất quán trên máy phát triển, môi trường kiểm thử và Production.
Một trong những nguyên nhân phổ biến nhất khiến ứng dụng chạy được trên máy lập trình viên nhưng thất bại khi triển khai là quản lý dependency không đúng cách.
Đó cũng là lý do nguyên tắc thứ hai của 12-Factor App nhấn mạnh:
Explicitly declare and isolate dependencies
Khai báo rõ ràng và cô lập toàn bộ dependency của ứng dụng.
Khai báo rõ ràng và cô lập toàn bộ dependency của ứng dụng.
Nguyên tắc này giúp ứng dụng có thể được triển khai lặp lại (repeatable deployment), giảm lỗi do khác biệt môi trường và là nền tảng của CI/CD hiện đại.
Dependency là gì?
Dependency là các thư viện, framework hoặc package mà ứng dụng cần để hoạt động.
Ví dụ:
- Python cần requests, netaddr, ncclient.
- Node.js cần Express, React hoặc Axios.
- Java cần Spring Boot hoặc Hibernate.
- .NET cần các package NuGet.
Nếu thiếu một dependency hoặc dùng sai phiên bản, ứng dụng có thể không build được hoặc hoạt động không chính xác.
Luôn khai báo Dependency một cách tường minh
12-Factor App khuyến nghị không bao giờ giả định rằng máy chủ đã cài sẵn các thư viện cần thiết.
Thay vào đó, mọi dependency phải được khai báo trong các file manifest.
Ví dụ:
Python
requirements.txtrequests
scrapy
nose
netaddr==0.7.19
ncclient>=0.6.1
Trong ví dụ trên:
- netaddr==0.7.19 yêu cầu đúng phiên bản 0.7.19.
- ncclient>=0.6.1 yêu cầu phiên bản tối thiểu là 0.6.1.
Sau đó chỉ cần chạy:
pip install -r requirements.txt
là toàn bộ môi trường sẽ được thiết lập tự động.
Mỗi nền tảng đều có Package Manager riêng
Hầu hết các ngôn ngữ lập trình đều có công cụ quản lý dependency:
Python
- pip
- requirements.txt
Node.js
- npm
- package.json
Java
- Maven
- Gradle
.NET
- NuGet
- JSON manifest
Các công cụ này giúp tự động tải đúng thư viện và đúng phiên bản, thay vì cài đặt thủ công trên từng máy.
Vì sao phải cô lập Dependency?
Khai báo dependency thôi là chưa đủ.
12-Factor App còn yêu cầu isolate dependencies – cô lập môi trường của từng ứng dụng.
Hãy tưởng tượng một máy chủ chạy hai ứng dụng Python:
- Ứng dụng A cần requests 2.25
- Ứng dụng B cần requests 2.32
Nếu cả hai cùng dùng thư viện cài đặt toàn cục (system-wide), việc nâng cấp cho ứng dụng B có thể làm ứng dụng A ngừng hoạt động.
Đây là nguyên nhân của rất nhiều sự cố trong môi trường Production.
Virtual Environment trong Python
Để tránh xung đột, Python sử dụng Virtualenv.
Ví dụ:
virtualenv myproject
Kích hoạt môi trường:
source myproject/bin/activate
Từ thời điểm đó:
- Thư viện chỉ được cài trong môi trường của ứng dụng.
- Không ảnh hưởng đến ứng dụng khác.
- Có thể dùng nhiều phiên bản khác nhau của cùng một package trên cùng một máy chủ.
Đây là một trong những thực hành quan trọng của phát triển Python hiện đại.
Container còn tiến thêm một bước
Ngày nay, Docker giúp cô lập dependency ở mức cao hơn.
Mỗi container chứa:
- Runtime
- Thư viện
- Framework
- Package
- Cấu hình cần thiết
Nhờ đó, ứng dụng luôn chạy trong đúng môi trường đã được kiểm thử, bất kể máy chủ bên dưới là Linux, Windows hay Cloud.
Đây cũng là lý do Docker và Kubernetes trở thành nền tảng của các kiến trúc Cloud-Native.
Lợi ích đối với CI/CD
Khi dependency được khai báo đầy đủ và cô lập, pipeline CI/CD chỉ cần:
pip install -r requirements.txt
hoặc
npm install
hay
mvn install
là có thể tự động dựng đúng môi trường để:
- Build.
- Chạy Unit Test.
- Chạy Integration Test.
- Đóng gói Artifact.
- Triển khai.
Không còn phụ thuộc vào việc máy chủ đã cài gì trước đó.
Điều này giúp quá trình triển khai có thể lặp lại nhiều lần với kết quả nhất quán (repeatable deployment), giảm đáng kể lỗi do khác biệt môi trường.
Best Practices
Một số nguyên tắc nên áp dụng trong các dự án DevOps hiện đại:
- Khai báo toàn bộ dependency trong file manifest.
- Chỉ định rõ phiên bản khi cần đảm bảo tính tương thích.
- Không dựa vào các package đã cài sẵn trên hệ điều hành.
- Cô lập dependency bằng Virtual Environment hoặc Container.
- Để CI/CD tự động cài đặt dependency thay vì thao tác thủ công.
- Thường xuyên cập nhật và kiểm tra các thư viện nhằm giảm rủi ro từ lỗ hổng bảo mật.
Kết luận
Nguyên tắc Dependencies của 12-Factor App nghe có vẻ đơn giản nhưng là nền tảng cho khả năng triển khai ổn định và tự động hóa.
Một ứng dụng hiện đại nên:
- Khai báo đầy đủ mọi dependency.
- Quản lý dependency bằng Package Manager.
- Cô lập môi trường của từng ứng dụng.
- Cho phép dựng toàn bộ môi trường chỉ với một lệnh.
Khi tuân thủ nguyên tắc này, các nhóm DevOps, Cloud Engineer và Platform Engineer có thể xây dựng các pipeline CI/CD đáng tin cậy, giảm lỗi do khác biệt môi trường và triển khai ứng dụng nhất quán trên máy phát triển, môi trường kiểm thử và Production.