Gặp gỡ Trần Quốc Toàn – Chuyên gia đạt top 2 Dockerfile Contest 2025 dự án Reactjs

Sự kiện Dockerfile Contest 2025 do DevOps Việt Nam tổ chức đã là nơi minh chứng cho sự sáng tạo kỹ thuật không giới hạn, đặc biệt trong việc container hóa ứng dụng Frontend. Việc tối ưu hóa container cho các ứng dụng Static Web đòi hỏi một triết lý triệt để về sự tinh gọn, bảo mật, và tốc độ phân phối nội dung

Trong hạng mục ReactJS, anh Trần Quốc Toàn đã chứng minh rằng sự tối giản không có giới hạn, xuất sắc giành vị trí TOP 2 Reactjs. Anh Toàn đã đưa ra một quyết định: xây dựng image runtime cuối cùng FROM SCRATCH (từ con số 0). Bài phỏng vấn độc quyền này sẽ đi sâu vào tư duy Just Enough của anh Toàn, chiến lược tự biên dịch các công cụ quan trọng, và cách anh thiết lập tiêu chuẩn mới về bảo mật bằng cách triệt tiêu mọi bề mặt tấn công trong container.

3330366a-6afc-43d8-a610-3deba972525f

Anh có thể chia sẻ đôi nét về kinh nghiệm của mình? Khi tham gia cuộc thi, mục tiêu chiến lược nào đã dẫn đến quyết định táo bạo là xây dựng Image Runtime cuối cùng từ con số 0 (FROM SCRATCH), không dựa trên bất kỳ base image nào? Triết lý kiến trúc của Anh khi chọn con đường tối giản này là gì?

Với nền tảng về Frontend/DevOps , mình hiểu rất rõ nỗi đau của việc deploy: sự tiện lợi của các base image có sẵn thường phải trả giá bằng hiệu năng và bảo mật. Chúng ta thường tối ưu từng kilobyte code JavaScript, nhưng lại đóng gói nó trong những container nặng nề và thừa thãi, mang theo quá nhiều rác các thư viện và dependencies mà ứng dụng không bao giờ chạm tới.

Vì vậy, khi đến với cuộc thi, mình quyết định không đi theo lối mòn và xây dựng runtime từ con số âm FROM SCRATCH. Đây không chỉ là việc thể hiện kỹ năng mà còn là sự khẳng định về quyền kiểm soát. mình muốn biết chính xác từng file, từng process đang chạy trong hệ thống của mình. Triết lý của mình là Just Enough vừa đủ: một kiến trúc chỉ giữ lại những gì thiết yếu nhất để vận hành, vừa tối ưu hiệu năng, vừa triệt tiêu rủi ro bảo mật.

Anh đã tự biên dịch một Binary Web Server Nginx tĩnh, thay vì sử dụng image Nginx có sẵn. Ý nghĩa chiến lược của việc này là gì? Theo Anh, làm thế nào để đo lường giá trị bảo mật và lợi ích về kích thước mà phương pháp tự biên dịch này mang lại so với các Base Image tiêu chuẩn?

Đúng là dùng một image có sẵn như nginx:alpine thì cực nhanh và tiện. Nhưng với mình, chạy được và chạy tối ưu là hai khái niệm hoàn toàn khác nhau. Mình chọn tự biên dịch Nginx vì mình muốn kiểm soát từng byte trong container của mình. Các bản phân phối mặc định thường kèm theo rất nhiều module dư thừa như mail, proxy hay uwsgi…, những thứ mà một trang web React tĩnh chẳng bao giờ cần. Giữ chúng lại đồng nghĩa với việc giữ cả rủi ro bảo mật, vì kích thước image lớn cũng đồng nghĩa bề mặt tấn công rộng hơn. Do đó, mình đã loại bỏ hoàn toàn những gì không cần thiết, chỉ giữ đúng những gì phục vụ cho việc phục vụ file tĩnh.

Về con số, sự khác biệt rất rõ ràng: một image chuẩn nginx:latest có thể nặng hơn 100MB, bản alpine khoảng 40MB, nhưng image mình build từ scratch chỉ vỏn vẹn chưa đến 10MB bao gồm Nginx binary, file tĩnh React và các thư viện cần thiết. Đây là sự tối ưu cực kỳ về băng thông và tốc độ pull image.

Về bảo mật, mình dùng các công cụ quét lỗ hổng như Trivy hay Grype. Nếu quét base image chuẩn, đôi khi vẫn còn các cảnh báo CVE Low hoặc Medium từ những gói hệ thống dư thừa. Trong khi đó, với image của mình, kết quả thường trả về Zero CVE. Quan trọng hơn cả, nếu hacker xâm nhập container, họ gần như không thể làm gì: không có shell, không có curl để tải mã độc, thậm chí ls cũng không. Đó chính là giá trị bảo mật cao mà mình hướng tới.

Trong Dockerfile, Anh đã thực hiện một kỹ thuật rất chuyên sâu là tự biên dịch một binary Healthcheck bằng ngôn ngữ C. Tại sao Anh không sử dụng một công cụ có sẵn (như curl hay wget từ Alpine) cho Healthcheck? Việc này đã giúp giải quyết vấn đề phụ thuộc và giảm diện tích tấn công như thế nào trong môi trường Runtime scratch?

Việc dùng curl hay wget trong một môi trường scratch gần như là một sự mâu thuẫn về mặt kiến trúc. Để chạy được curl, mình sẽ phải kéo theo một loạt thư viện liên kết động như libc, musl, hoặc thậm chí một phần hệ điều hành tối thiểu. Điều này phá vỡ hoàn toàn triết lý tối giản tuyệt đối của scratch.

Bên cạnh đó, curl hay wget là những công cụ rất dễ bị kẻ tấn công lợi dụng trong mô hình Living off the Land. Nếu một hacker lọt vào container, họ có thể chỉ đơn giản là chạy curl để tải mã độc về, hoặc đẩy dữ liệu nội bộ ra ngoài.

Vì vậy, mình quyết định loại bỏ hoàn toàn các tiện ích này và tự viết một chương trình healthcheck bằng C. mình chọn cách nguyên bản nhất: sử dụng socket syscall thuần, biên dịch dưới dạng static binary, không phụ thuộc vào bất kỳ thư viện nào của hệ điều hành. Kết quả là mình có một file thực thi độc lập, siêu nhẹ, chỉ làm đúng một việc duy nhất: mở kết nối TCP để kiểm tra healthcheck của ứng dụng. Bằng cách này, mình giữ cho môi trường runtime tinh khiết, không tạp chất, không công cụ dư thừa, và không mở rộng bề mặt tấn công.

Anh đã sử dụng các công cụ quản lý dependencies hiện đại (như pnpm) và tối ưu hóa cách thu thập các thư viện chia sẻ (shared libraries) bằng lệnh ldd. Theo Anh, đâu là nguyên tắc vàng trong việc tổ chức Docker Layer để đạt tốc độ Build cao nhất cho các dự án Frontend? Và chiến lược thu thập thư viện này quan trọng như thế nào đối với tính ổn định của Image cuối cùng?

Nguyên tắc của mình là luôn sắp xếp các layer theo mức độ thay đổi. Những phần gần như cố định như dependencies sẽ được đưa lên trước, còn những phần thay đổi liên tục như source code thì đặt xuống sau. Cách tổ chức này phù hợp với cơ chế cache của Docker: khi mình sửa code và build lại, Docker chỉ cần xử lý những phần thật sự thay đổi, còn các layer ổn định như bước cài dependencies vẫn được tái sử dụng, giúp tốc độ build nhanh hơn rất nhiều. Việc dùng pnpm cũng đóng vai trò lớn, làm giảm đáng kể thời gian I/O và không gian lưu trữ.

Còn việc dùng ldd để thu thập thư viện, mình xem đó như một bước kiểm tra hành trang mà Nginx cần mang theo để sống được trong môi trường scratch. Vì scratch hoàn toàn trống rỗng, không có thư viện hệ thống nào kèm theo, mình buộc phải tự thu thập đúng những thư viện cần thiết. Cách làm này giúp mình đảm bảo rằng image cuối cùng chạy ổn định ở mọi nơi từ máy development đến production mà không bị ảnh hưởng bởi hệ điều hành của host.

Dockerfile của Anh có sự quan tâm đặc biệt đến việc tạo người dùng và nhóm tối thiểu (nginx:x:101:101) để tăng cường bảo mật. Anh đánh giá thế nào về tầm quan trọng của việc phân quyền Non-root trong môi trường Production hiện đại? Và Anh dự đoán xu hướng công nghệ lớn nhất nào sẽ định hình cách chúng ta triển khai Web tĩnh trong tương lai?

Trong môi trường Production hiện đại, Nguyên tắc đặc quyền tối thiểu gần như là luật bất thành văn. Việc mình tạo user 101:101 và buộc container chạy ở chế độ non-root không chỉ là thao tác kỹ thuật, mà là một tư duy defense-in-depth đúng nghĩa. Nếu một lỗ hổng bị khai thác, kẻ tấn công cũng chỉ rơi vào một user vô danh không có quyền ghi hệ thống, không cài được mã độc, và hoàn toàn không thể động chạm vào Host. Container lúc này trở thành một hộp cát đúng nghĩa, hạn chế tối đa bề mặt tấn công.

Nhìn xa hơn, mình tin rằng tương lai triển khai Web sẽ nghiêng mạnh về các mô hình Distroless. Dù FROM scratch mang lại độ sạch tuyệt đối, nhưng nó cũng đi kèm những hạn chế tự nhiên như khó debug và yêu cầu kiến thức hệ thống sâu. Distroless sẽ là lựa chọn cân bằng tốt giữa sự tối giản và khả năng vận hành thực tế.

Tuy nhiên, dù trong môi trường thực tế, Distroless có thể là lựa chọn lý tưởng, nhưng với bài toán hiện tại trong Dockerfile Contest 2025 nơi tính kiểm soát và độ thuần khiết được ưu tiên FROM SCRATCH vẫn là lựa chọn phù hợp nhất. Nó cho phép mình giữ mọi thứ ở trạng thái tinh gọn tuyệt đối và biết chính xác từng thành phần tồn tại trong image. Triết lý triển khai sẽ dần dịch chuyển sang Application-centric: chỉ mang theo đúng ứng dụng và các dependency tối thiểu, loại bỏ hoàn toàn lớp OS thừa thãi.

Cuối cùng, với tư cách là người chiến thắng có giải pháp kỹ thuật chuyên sâu, Anh có Bài học quan trọng nhất nào muốn chia sẻ với cộng đồng về Tư duy Kiến trúc Container? Và Anh có muốn nhắn gửi lời nào đến những người bạn đồng nghiệp không?

Bài học quan trọng nhất mà mình rút ra là: Mọi chi tiết trong container đều có ý nghĩa. Trước đây mình chỉ xem Docker như một công cụ đóng gói tiện lợi, nhưng quá trình tham gia cuộc thi khiến mình hiểu rằng Docker thực sự là bài toán về tư duy kiến trúc và quản lý tài nguyên. Một file thừa, một dependency dư nhìn thì vô hại nhưng trong môi trường thật, nó có thể trở thành lỗ hổng bảo mật hoặc điểm nghẽn hiệu năng. Việc hiểu chính xác ứng dụng của mình cần gì và không cần gì không phải là sự cầu toàn thái quá; đó là trách nhiệm tự nhiên của một kỹ sư khi xây dựng một sản phẩm có chất lượng.

Lời nhắn gửi đến cộng đồng: Đừng chỉ dừng lại ở mức chạy được. Hãy tìm hiểu nó chạy như thế nào và tại sao nó chạy được. Thực tế scratch hay distroless thoạt nhìn có vẻ khô khan, phức tạp, nhưng càng đi sâu, bạn sẽ càng thấy nó mở ra một góc nhìn rất thú vị về Linux, về hệ thống, và cách một ứng dụng thật sự vận hành dưới lớp vỏ container. Cứ thử, cứ vọc, cứ sai rồi sửa. Và khi bạn tìm ra một cách làm hay ho, hãy chia sẻ nó. Bởi cuối cùng, giá trị của một kỹ sư không chỉ nằm ở những gì họ biết, mà ở những gì họ mang lại cho những người xung quanh.

019abc27-cd46-7526-8356-f19b58a5e732

Chiến thắng của anh Trần Quốc Toàn không chỉ là một thành tựu kỹ thuật mà còn là lời tuyên bố về tầm quan trọng của tư duy kiến trúc container. Bằng việc kiên quyết xây dựng image FROM SCRATCH , tự biên dịch Web Server , và tạo ra Healthcheck binary riêng , anh đã chứng minh rằng việc hiểu chính xác ứng dụng cần gì và không cần gì là trách nhiệm cốt lõi của một kỹ sư. Triết lý Just Enough của anh đã thiết lập một tiêu chuẩn mới về khả năng kiểm soát tuyệt đối, an toàn bảo mật, và hiệu suất siêu việt cho ứng dụng Web tĩnh.

Chúng tôi xin chân thành cảm ơn anh Trần Quốc Toàn đã dành thời gian chia sẻ những bài học vô giá và chúc anh tiếp tục gặt hái nhiều thành công hơn nữa.

Tham khảo chi tiết Dockerfile của anh Toàn tại: Dockerfile Contest 2025

Thông tin đáng chú ý

Sự kiện phát trực tiếp

Event Thumbnail
Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận