Dev Containers và GitHub Codespaces: đội FDE và đội khách dùng chung một môi trường
Ngày đầu ở site khách hay mất trắng vì cài đặt môi trường. Một file JSON trong repo có thể giúp cả phòng lấy lại ngày đó.

Tóm tắt nhanh
- devcontainer.json nằm trong thư mục .devcontainer của repo. Cấu hình môi trường vì thế có version và được chia sẻ như code.
- Tag image có thể đổi, digest thì không. Ghim bằng digest để mọi người nhận đúng một image.
- Codespaces chạy cùng cấu hình đó trên máy ảo do GitHub quản lý, không cần Docker trên laptop khách. Prebuild giúp tạo codespace nhanh hơn.
Có một câu mà FDE nào cũng từng nghe trong buổi sáng đầu tiên ở site khách: “Trên máy anh chạy được, sao máy em lại không?” Sau câu đó thường là nửa ngày dò phiên bản Python, driver database và một extension ai đó quên cài.
Dev Containers giải quyết đúng chỗ này, và cách làm rất đơn giản. Toàn bộ môi trường được mô tả trong một file nằm ngay trong repo. Ai mở repo cũng có cùng một bộ công cụ, dù là người của bạn hay của khách.
Với FDE thì phần lợi rất cụ thể. Bạn hay phải làm việc chung với kỹ sư phía khách, những người không biết stack của bạn và không có thời gian để đoán. Nếu họ clone repo xong là gõ được lệnh đầu tiên ngay, buổi làm việc chung mở đầu bằng vấn đề của khách thay vì vấn đề cài đặt.
Một file JSON mô tả cả môi trường
Development Containers là một đặc tả mở do Microsoft đứng tên, công bố tại containers.dev. Nó cho phép bổ sung vào container những công cụ và thiết lập phục vụ việc lập trình, để biến container thành một môi trường phát triển đầy đủ.
File quan trọng nhất là devcontainer.json, định dạng đầu tiên của đặc tả. Nó chứa metadata và các thiết lập cần để dựng dev container.
Theo GitHub Docs, cấu hình nằm trong thư mục .devcontainer của repo. Nhờ vậy, cấu hình môi trường được commit, review và revert như mọi dòng code khác.
GitHub Codespaces là nửa còn lại. Mỗi codespace là môi trường phát triển chạy trong một Docker container, trên máy ảo do GitHub vận hành, và đọc cùng file cấu hình đó.
Năm bước dựng môi trường chung
Thử hình dung bạn đang dựng một pipeline xử lý dữ liệu cho khách. Đội bạn dùng Mac, hai kỹ sư phía khách dùng laptop công ty. Thay vì gửi họ một trang README dài, bạn đi năm bước sau.
Bước 1. Tạo thư mục .devcontainer ở gốc repo và một file devcontainer.json bên trong.
Bước 2. Chọn image và ghim nó. Thuộc tính image là tên một image trong container registry, nên đây là chỗ khóa phiên bản. Tag có thể bị trỏ sang image khác bất cứ lúc nào, còn digest thì bất biến, như Adrian Mouat của Chainguard giải thích.
Bước 3. Thêm các extension mà cả đội cần. File hoàn chỉnh trông như sau:
{
"name": "pipeline-khach-hang",
"image": "mcr.microsoft.com/devcontainers/python@sha256:<digest-ban-da-kiem-tra>",
"customizations": {
"vscode": {
"extensions": ["ms-python.python"]
}
}
}
Phần <digest-ban-da-kiem-tra> là chỗ bạn dán chuỗi digest lấy từ registry cho đúng image đã thử. Khi mới bắt đầu, dùng tag cho tiện cũng được, nhưng trước khi trao repo cho khách, hãy đổi sang digest.
Bước 4. Trong VS Code có extension Dev Containers, chạy lệnh “Dev Containers: Reopen in Container” từ thư mục repo đang mở. Editor dựng container theo devcontainer.json rồi mở lại thư mục bên trong đó.
Bước 5. Nhờ một đồng nghiệp chưa từng đụng vào repo mở thử trên máy của họ. Thứ gì họ phải tự cài thêm, đưa vào file và commit lại. Đây là cách biết file đã đủ hay chưa.
Nếu đội bạn làm nhiều dự án cho nhiều khách trên cùng một stack, hãy dùng chung một image đã ghim cho tất cả các repo. Mỗi lần nâng phiên bản, bạn chỉ cần thử một image thay vì nhiều môi trường lệch nhau.
Local hay Codespaces: câu hỏi đầu tiên là dữ liệu nằm ở đâu
Chạy dev container trên máy local thì máy đó phải cài và cấu hình Docker, theo tài liệu VS Code. Đây là điểm cần hỏi khách ngay tuần đầu, vì hai lý do.
Laptop công ty thường bị khóa quyền cài phần mềm, và Docker Desktop chỉ miễn phí cho doanh nghiệp dưới 250 nhân viên và dưới 10.000.000 USD doanh thu năm, nên đội khách lớn có thể cần gói trả phí.
Codespaces bỏ được bước đó vì container chạy trên máy ảo của GitHub. Bù lại, code và có thể cả dữ liệu mẫu sẽ nằm trên hạ tầng của GitHub.
Với khách trong ngành tài chính hay y tế, đây là câu hỏi cho đội bảo mật của họ, không phải câu hỏi bạn tự trả lời thay. Điểm hay là cùng một devcontainer.json chạy được ở cả hai nơi, nên bạn không phải chọn một lần cho mãi mãi.
Còn một giới hạn thực tế là tốc độ. Repo lớn có thể dựng codespace khá lâu. GitHub có prebuild: source, extension và dependency được cài sẵn, nên codespace mới lên nhanh hơn. Bấm giờ lần tạo đầu tiên, nếu thấy chậm thì bật prebuild.
Hai lỗi khiến môi trường chung hỏng ngay tuần đầu
Lỗi đầu tiên là để image trôi theo tag. Hai người mở repo cách nhau một tháng có thể nhận hai image khác nhau, và lợi ích “giống hệt nhau” biến mất. Ví dụ ở bước 2 tồn tại chính là để chặn lỗi này.
Lỗi thứ hai nguy hiểm hơn: đặt secret vào devcontainer.json. File này được commit vào repo, ai có quyền đọc repo đều thấy, nên API key hay mật khẩu database của khách tuyệt đối không được nằm trong đó. Chỉ để cấu hình công cụ trong file; credential nên lấy từ kho secret mà đội bảo mật của khách chấp thuận.
Học gì trước, và cách khoe kỹ năng này
Hãy bắt đầu từ cái nhỏ nhất chạy được: một image đã ghim cùng danh sách extension. Đừng nhồi mọi thứ vào ngày đầu; để bước 5 cho bạn biết còn thiếu gì.
Về sự nghiệp, kỹ năng này dễ chứng minh hơn bạn nghĩ. Một repo portfolio có thư mục .devcontainer cho nhà tuyển dụng thấy bạn nghĩ đến người dùng tiếp theo của code.
Trong CV, một câu về thời gian onboarding kỹ sư phía khách trước và sau khi có dev container có giá trị hơn nhiều so với việc liệt kê Docker trong mục kỹ năng, miễn là bạn đo được con số thật. Khi đọc JD có những cụm như “developer experience” hay “onboard customer engineers”, đó là chỗ để kể câu chuyện này.
FDE giỏi được nhớ đến vì khách tự chạy được hệ thống sau khi họ rời đi. Một file devcontainer.json tốt là cách rẻ nhất để làm được điều đó ngay từ ngày đầu.
Bài này có hữu ích không?
Cảm ơn bạn đã góp ý!
9 nguồn
- Development Containers
- devcontainers/spec: Development Containers Specification
- Dev Container metadata reference
- Introduction to dev containers - GitHub Docs
- What are GitHub Codespaces? - GitHub Docs
- About GitHub Codespaces prebuilds - GitHub Docs
- Developing inside a Container - Visual Studio Code
- How I learned to stop worrying and love the latest tag (Adrian Mouat, Chainguard) · 2026-02-11
- Docker Plans FAQs | Docker