•10 min read

Hướng dẫn Dev Containers: Môi trường Docker trong VS Code

Hướng dẫn Dev Containers: Môi trường Docker trong VS Code

Tôi từng mất cả một sprint để truy tìm một lỗi chỉ xuất hiện trên máy của một nhà phát triển. Thủ phạm ư? Một sự không khớp nhỏ về phiên bản Node.js. Chúng tôi đã dành ba ngày họp hành, xem xét code và những buổi debug đầy bực bội. Việc sửa lỗi chỉ mất năm phút sau khi chúng tôi tìm ra nó.

Trải nghiệm đó đã thay đổi cách tôi suy nghĩ về môi trường phát triển.

Vấn đề "chạy được trên máy của tôi" đã ám ảnh ngành của chúng ta hàng thập kỷ. Chúng ta đã thử mọi thứ: các script thiết lập phức tạp, các file README chi tiết, các trang wiki bị bỏ xó chỉ trong vài tuần. Chẳng có gì hiệu quả. Cho đến khi tôi khám phá ra Dev Containers.

Audio Briefing
0:00 / 0:00

Dev Container Chính Xác Là Gì?

Dev Container là một môi trường phát triển dựa trên Docker mà bạn cấu hình một lần và mọi người trong nhóm của bạn đều nhận được chính xác cùng một thứ. Code của bạn chạy bên trong một container đã được cài đặt sẵn tất cả các dependency, công cụ và cấu hình.

Hãy nghĩ nó như một máy ảo, nhưng nhẹ hơn và có thể loại bỏ. Bạn có thể hủy nó, tạo lại nó và chia sẻ nó chỉ với một file cấu hình duy nhất.

Thiết lập nằm trong thư mục .devcontainer ở thư mục gốc của dự án. Bên trong đó, bạn định nghĩa image cơ sở của mình, các extension mà nhóm của bạn cần và bất kỳ script nào chạy sau khi tạo. Khi ai đó mở dự án trong VS Code, họ sẽ được nhắc mở lại trong container. Một cú nhấp chuột, và họ đã sẵn sàng.

Nghe có vẻ phức tạp không? Lúc đầu tôi cũng nghĩ vậy.

Advertisement

Nỗi Đau Mà Tôi Đang Cố Gắng Giải Quyết

Trước Dev Containers, tôi làm việc trên một dự án Node.js mà một nửa nhóm sử dụng macOS và một nửa sử dụng Linux. Nghe có vẻ ổn, phải không? Ngoại trừ các dependency module gốc của chúng tôi được biên dịch khác nhau trên mỗi nền tảng. Cứ vài tuần một lần, môi trường cục bộ của ai đó lại bị lệch.

Tôi nhớ đã chứng kiến một nhà phát triển mới phải vật lộn hai ngày chỉ để xây dựng được frontend của chúng tôi. Tài liệu hướng dẫn onboarding dài tám trang. Nó đề cập đến các bước đã không còn cần thiết trong nhiều tháng. Tất cả chúng tôi đều quên cập nhật nó mỗi khi có gì đó thay đổi.

Đó không phải là một câu chuyện hiếm gặp. Thời gian các nhà phát triển dành để chiến đấu với môi trường của họ là thời gian không viết tính năng.

Thiết Lập Dev Container Đầu Tiên Của Bạn

Vẻ đẹp nằm ở sự đơn giản. Bắt đầu với cấu trúc này:

your-project/
├── .devcontainer/
│   ├── devcontainer.json
│   └── Dockerfile

File devcontainer.json là nơi mọi thứ kết hợp lại. Đây là một cấu hình cơ bản mà tôi đã bắt đầu:

Tạo file cấu hình

Thêm một .devcontainer/devcontainer.json vào thư mục gốc dự án của bạn. File này cho trình chỉnh sửa của bạn biết cách xây dựng và kết nối với container phát triển của bạn.

Chỉ định image cơ sở của bạn

Chọn một Docker image phù hợp với stack của bạn. Đối với các dự án Node.js, tôi thường bắt đầu với mcr.microsoft.com/devcontainers/javascript-node. Kho lưu trữ của Microsoft có image cho hầu hết mọi stack phổ biến.

Cài đặt công cụ của bạn

Sử dụng thuộc tính features để thêm các công cụ phổ biến mà không cần viết các lệnh Dockerfile tùy chỉnh. Cần Git, Docker CLI, hay các công cụ cơ sở dữ liệu? Mỗi thứ một dòng.

Thêm các extension của bạn

Liệt kê các extension VS Code mà nhóm của bạn cần. Chúng sẽ được cài đặt tự động khi container khởi động. Các dự án JavaScript của tôi luôn có ESLint, Prettier và extension Docker.

Đây là một trong những cấu hình thực tế của tôi trông như thế nào:

{
  "name": "My Project Development",
  "image": "mcr.microsoft.com/devcontainers/javascript-node",
  "features": {
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },
  "extensions": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode"
  ]
}

Chỉ vậy thôi. Mười bốn dòng và toàn bộ nhóm của tôi làm việc trong các môi trường giống hệt nhau.

Điều Gì Xảy Ra Khi Bạn Mở Một Dev Container?

Lần đầu tiên bạn mở một dự án được cấu hình theo cách này, trình chỉnh sửa của bạn (VS Code hoặc Cursor) sẽ phát hiện cấu hình. Nó xây dựng Docker image, tạo một container và kết nối bạn với nó. Bạn đang làm việc bên trong container, không phải trên máy chủ của bạn.

Terminal của bạn bây giờ là một phiên bash bên trong container đó. Các extension của bạn chạy ở đó. Hệ thống file của bạn được gắn từ máy chủ của bạn, vì vậy bạn chỉnh sửa bình thường, nhưng việc thực thi diễn ra bên trong container.

Lần xây dựng đầu tiên mất vài phút. Sau đó, việc khởi động container chỉ mất vài giây.

Advertisement

Kết Quả Khiến Tôi Bất Ngờ

Tôi đã mong đợi Dev Containers sẽ làm tăng chi phí. Tôi đã mong đợi chúng sẽ chậm chạp hoặc phức tạp. Nhưng những gì tôi tìm thấy lại hoàn toàn ngược lại.

Nhóm của tôi đã onboarding ba nhà phát triển mới trong những tháng tiếp theo. Mỗi người đều viết code trong vòng hai mươi phút sau khi clone repository. Không có "bạn có thể giúp tôi cài đặt X không", không có "bạn đang dùng phiên bản Y nào", không có bí ẩn nào cả.

Chúng tôi cũng hoàn toàn không còn các lỗi liên quan đến môi trường. Khi mọi người chạy cùng một hệ điều hành, cùng công cụ, cùng phiên bản, những loại vấn đề đó đơn giản là biến mất.

Những cải thiện về năng suất không rõ rệt một cách đáng kể. Không có gì xuất hiện trong báo cáo sprint. Nhưng tôi nhận thấy nó ở những điều nhỏ hơn: ít tin nhắn Slack về các vấn đề thiết lập hơn, nhiều thời gian hơn trong trạng thái tập trung, xem xét code nhanh hơn.

Khi Nào Dev Containers Có Ý Nghĩa

Tôi đã học được qua kinh nghiệm rằng chúng phát huy tác dụng tốt nhất ở đâu.

Các dự án nhóm hưởng lợi nhiều nhất. Khi nhiều nhà phát triển cùng làm việc trên một codebase, sự nhất quán của môi trường mang lại lợi ích kép.

Các tình huống onboarding là những chiến thắng rõ ràng. Mọi nhân viên mới mà tôi thấy sử dụng chúng đều làm việc hiệu quả nhanh hơn những người tuân theo tài liệu thiết lập truyền thống.

Các dependency phức tạp trở nên dễ quản lý. Các dự án cần cơ sở dữ liệu, bộ nhớ đệm hoặc các công cụ chuyên biệt là những ứng cử viên hoàn hảo.

Sự tương đồng CI/CD là một lợi ích tiềm ẩn. Nếu các bản dựng sản xuất của bạn chạy trong container, dev container cho phép các nhà phát triển phát hiện các vấn đề tương tự cục bộ.

Tuy nhiên, chúng không phải lúc nào cũng là câu trả lời. Các script cá nhân nhanh chóng, các thử nghiệm một file hoặc khám phá tạm thời không cần đến sự phức tạp này.

Một Số Điều Tôi Ước Mình Biết Sớm Hơn

Đừng tùy chỉnh image cơ sở của bạn quá nhiều. Tôi đã mắc lỗi đó một lần, xây dựng một image mất hai mươi phút để xây dựng lại mỗi khi các dependency thay đổi. Hãy tuân thủ các image cơ sở đã được thiết lập và thêm các tùy chỉnh của bạn lên trên.

Bắt đầu đơn giản. File devcontainer.json đầu tiên của tôi quá phức tạp. Tôi có các tính năng và script mà tôi không bao giờ sử dụng. Chỉ thêm mọi thứ khi bạn cần chúng.

Hệ thống file máy chủ được gắn kết, nhưng hiệu suất có thể bị ảnh hưởng đối với các thư mục node_modules lớn. Nếu bạn gặp phải vấn đề này, hãy tìm hiểu các chiến lược lưu trữ trong tài liệu của Microsoft.

Vấn Đề Thực Sự Được Giải Quyết

Chúng ta đã chấp nhận sự không nhất quán của môi trường như một chi phí không thể tránh khỏi của việc phát triển phần mềm cộng tác. Dev Containers đã thay đổi giả định đó đối với tôi.

Ba năm sử dụng chúng hàng ngày, tôi không thể tưởng tượng được việc quay trở lại cách cũ. Cứ vài tháng lại có một nhà phát triển mới phản đối, nói rằng nó không cần thiết. Tất cả họ đều đã thay đổi suy nghĩ trong tuần đầu tiên.

Cái cớ "chạy được trên máy của tôi" ư? Nó đã không còn là một cụm từ trong từ điển của nhóm chúng tôi. Chúng tôi không cần các tài liệu onboarding phức tạp nữa. Chúng tôi không cần các buổi debug "hôm qua nó vẫn chạy" nữa.

Một Docker container tiêu chuẩn chạy một runtime ứng dụng (như một máy chủ Node). Một Dev Container biến container thành môi trường phát triển hoàn chỉnh của bạn, cài đặt các extension IDE, công cụ CLI dành cho nhà phát triển, trình gỡ lỗi và máy chủ ngôn ngữ trực tiếp bên trong container.

File .devcontainer/devcontainer.json hướng dẫn extension VS Code Dev Containers cách xây dựng Docker image, ánh xạ các cổng máy chủ, gắn các volume dự án và tự động cấu hình cài đặt không gian làm việc và các extension.

Để loại bỏ chi phí hiệu suất bind-mount trên macOS/Windows, hãy clone các repository trực tiếp vào một Docker volume được đặt tên bằng cách sử dụng lệnh Dev Containers: Clone Repository in Named Container Volume trong VS Code.


Bạn Cũng Có Thể Thích

Share this article:

Stay Updated

Get the latest posts delivered straight to your inbox.

Free Developer Utilities

Free In-Browser Developer Tools

Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.

Explore Tools
Advertisement