·

Docker MCP với Claude Code CLI and VS Code

Cài đặt Docker MCP trong Claude Code CLI and VS Code để AI agent có thể quản lý container, image và log ngay trong trình soạn thảo.

Ở bài trước bạn đã biết Docker MCP là gì và những rủi ro khi cho agent quyền truy cập Docker socket. Bài này đi thẳng vào thực hành: cài Docker MCP cho Claude Code CLI và VS Code (qua Claude Code extension), rồi dùng nó cho hai việc mình làm hàng ngày nhất — chẩn đoán build container bị fail, và inspect container đang chạy để tìm bug môi trường (env-specific bug) mà không cần mở thêm terminal tab nào.

Điểm khác biệt lớn nhất giữa dùng Docker MCP trong Claude Code so với gõ tay docker CLI không phải là tốc độ gõ lệnh — mà là việc agent giữ toàn bộ log, output, và suy luận trong cùng một luồng hội thoại, nên bạn hỏi tiếp câu follow-up mà không phải scroll lại terminal để nhớ context.

Cài Đặt Và Kết Nối Docker MCP Với Claude Code

Trước khi add MCP server, đảm bảo Docker daemon đang chạy và docker CLI trên máy bạn đã login đúng context muốn dùng:

docker context ls
docker info --format '{{.ServerVersion}}'

Với Claude Code CLI, cách nhanh nhất là dùng command add MCP server dạng stdio, chạy Docker MCP Toolkit's gateway như một process con:

claude mcp add docker -- docker mcp gateway run

Nếu bạn muốn commit config vào repo để cả team dùng chung, thêm block vào file .mcp.json ở root project:

{
  "mcpServers": {
    "docker": {
      "command": "docker",
      "args": ["mcp", "gateway", "run"],
      "env": {
        "DOCKER_HOST": "unix:///var/run/docker.sock"
      }
    }
  }
}

Sau khi add, verify kết nối:

claude mcp list

Trong session Claude Code, gõ /mcp để xem danh sách server đang active kèm trạng thái connected/error và danh sách tool nó expose (list_containers, build_image, get_logs, exec_in_container...). Nếu báo lỗi kết nối, thường do Docker daemon chưa chạy, hoặc user hiện tại chưa nằm trong group docker (trên Linux, cần sudo usermod -aG docker $USER rồi mở lại shell).

Với VS Code, mở Claude Code extension, vào panel MCP Servers trong Settings, add server bằng đúng command/args như trên qua UI — hoặc đơn giản hơn, mở cùng workspace đã có .mcp.json ở root, extension sẽ tự nhận diện và load lại server không cần config thêm. Đây là lý do nên luôn commit .mcp.json (không chứa secret) vào git, để cả team CLI và VS Code dùng chung một cấu hình duy nhất.

Kiểm tra quyền hạn trước khi giao task

Trước khi giao bất kỳ task có side-effect (build, remove, restart) cho agent, hỏi thử một prompt vô hại để xác nhận agent connect đúng Docker context và server đã sẵn sàng:

List toàn bộ image hiện có trên máy, kèm size và created time, sắp xếp
theo size giảm dần.

Nếu kết quả khớp với những gì bạn biết là đúng (không có image lạ, không thiếu image quen), coi như kết nối đã ổn để chuyển sang các task thật.

Mẹo: Trong VS Code, giữ file .mcp.json ở root project và ignore riêng phần env chứa path cá nhân (dùng biến môi trường thay vì hardcode) — như vậy CLI và extension luôn đồng bộ cấu hình, và bạn không vô tình commit DOCKER_HOST chỉ đúng trên máy mình.

Chẩn Đoán Build Container Thất Bại Từ Layer Log

Build container fail là loại lỗi mà log thường dài, lộn xộn, và nguyên nhân thật nằm ở một dòng nhỏ giữa hàng trăm dòng cache/pull layer. Đây chính là việc AI agent làm tốt hơn con người: đọc toàn bộ log, lọc noise, chỉ ra đúng dòng gây lỗi.

Trước tiên, luôn build với flag hiển thị log đầy đủ từng layer (BuildKit — engine build mới của Docker, cho log chi tiết hơn build engine cũ):

docker buildx build --progress=plain -t myapp:debug .

Với Docker MCP, bạn không cần tự chạy lệnh này rồi paste log vào chat — agent gọi trực tiếp tool build_image (nhận context_path, dockerfile, tags làm input) và đọc output ngay trong tool result. Prompt mẫu:

Build image từ Dockerfile trong thư mục hiện tại, tag "myapp:debug".
Build đang fail. Hãy:
1. Chạy build và lấy toàn bộ log, bao gồm log của từng layer/step.
2. Xác định đúng step nào fail (số thứ tự step, câu lệnh RUN/COPY nào).
3. Trích dẫn nguyên văn dòng error cuối cùng trước khi build dừng lại.
4. Đưa ra nguyên nhân gốc rễ khả năng cao nhất, không đoán chung
   kiểu "có thể do dependency".

Một vài nguyên nhân build fail phổ biến mà agent sẽ gặp và cách nó nên chẩn đoán:

Triệu chứng trong log Nguyên nhân thường gặp Cách agent nên xác nhận
COPY failed: file not found Sai đường dẫn context, hoặc file bị .dockerignore loại Đọc .dockerignore, so với đường dẫn COPY trong Dockerfile
npm ERR! code ENOTFOUND / pip install timeout Container build không có network, hoặc registry private cần auth Kiểm tra build có --network=host hay proxy config không
apt-get update fail với lỗi GPG/repo Base image dùng repo đã deprecated (ví dụ Debian version cũ hết support) Kiểm tra tag base image trong FROM, so với changelog image đó
Step build lại từ đầu dù code không đổi Cache bị invalidate do thứ tự COPY sai (COPY code trước khi COPY package.json) Đọc thứ tự các instruction trong Dockerfile, so với best practice cache layer
exit code 137 ngay giữa build Build bị OOM-killed do compile/bundle tốn RAM (ví dụ webpack build) Kiểm tra memory limit của builder, đề xuất tăng hoặc build multi-stage nhẹ hơn

Khi agent trả lời, luôn yêu cầu nó trích dẫn đúng số step và dòng log gốc — tránh trường hợp nó tổng hợp mơ hồ "có lỗi ở bước cài dependency" mà không chỉ rõ dependency nào, phiên bản nào.

Mẹo: Luôn thêm --progress=plain (hoặc để agent tự thêm flag này khi gọi build) trước khi nhờ AI chẩn đoán — output dạng progress bar rút gọn của Docker CLI thường bị cắt mất chi tiết layer mà agent cần để chỉ đúng nguyên nhân.

Kiểm Tra Container Đang Chạy, Env Var Và Network Ngay Từ Terminal

Nhiều bug "chỉ xảy ra trong container, không xảy ra khi chạy local" thực chất là do khác biệt về biến môi trường, DNS, hay network mode giữa container và máy host. Docker MCP cho agent quyền đọc trực tiếp các thông tin này mà không cần bạn tự gõ docker inspect rồi jq để lọc.

Prompt mẫu khi nghi ngờ bug do env var thiếu hoặc sai:

Container "api-service" đang chạy nhưng không kết nối được database.
Hãy:
1. Lấy toàn bộ biến môi trường (env) đang set trong container này.
2. So sánh với danh sách biến required trong file .env.example của repo
   (tôi sẽ paste nội dung file này).
3. Chỉ ra biến nào thiếu, hoặc có giá trị khác thường (ví dụ host là
   "localhost" trong khi container không thể tự kết nối localhost của host).

Đây là lỗi cực phổ biến với dev mới: đặt DATABASE_HOST=localhost trong container, quên rằng localhost bên trong container trỏ vào chính container đó, không phải máy host — cần host.docker.internal (Mac/Windows) hoặc network alias của service trong docker compose.

Với network, agent có thể đọc cấu hình network mà container đang tham gia:

Container "worker" không gọi được tới container "redis" qua hostname
"redis". Hãy inspect network mà cả hai container đang tham gia, xác nhận
chúng có nằm trong cùng Docker network không, và DNS resolution giữa
chúng có hoạt động không (kiểm tra qua exec lệnh "getent hosts redis"
bên trong container "worker" nếu tool hỗ trợ exec).

Agent sẽ gọi inspect_container để lấy phần NetworkSettings.Networks, so sánh network ID giữa hai container, và nếu server có expose exec_in_container, thử chạy getent hosts redis hoặc nslookup redis để xác nhận DNS resolve được hay không — bằng chứng chắc chắn hơn nhiều so với suy đoán.

Đọc resource usage khi nghi ngờ container bị throttle

Container chạy chậm bất thường nhiều khi không phải do code mà do bị giới hạn CPU/memory. Yêu cầu agent đọc get_stats:

Lấy CPU và memory usage real-time của toàn bộ container trong project
này, liệt kê dưới dạng bảng, đánh dấu container nào đang dùng gần sát
memory limit (trên 85%).

Mẹo: Khi debug network giữa container, luôn yêu cầu agent xác nhận bằng một lệnh thực thi thật (ping, nslookup, curl) qua exec_in_container thay vì chỉ đọc config JSON — config đúng không đảm bảo runtime hoạt động đúng, nhất là khi có firewall rule hay DNS cache cũ.

Prompt AI Tối Ưu Dockerfile Về Kích Thước Và Build Cache

Sau khi build đã chạy được, bước tiếp theo mọi senior engineer nên làm là tối ưu Dockerfile — vì image nhẹ hơn nghĩa là deploy nhanh hơn, ít bề mặt tấn công (attack surface) hơn, và build cache hiệu quả hơn nghĩa là CI nhanh hơn đáng kể.

Prompt mẫu để agent review và đề xuất tối ưu:

Đọc Dockerfile này (tôi paste nội dung), rồi phân tích:
1. Có đang dùng multi-stage build chưa? Nếu chưa, đề xuất tách stage
   build và stage runtime.
2. Base image có đang dùng bản full (ví dụ "node:20") hay có thể đổi
   sang "node:20-alpine" hoặc "node:20-slim" để giảm size?
3. Thứ tự COPY có tối ưu cache chưa (COPY package.json/lock file
   trước khi COPY toàn bộ source code)?
4. Có instruction nào tạo layer thừa không cần thiết (ví dụ nhiều RUN
   liên tiếp có thể gộp lại bằng &&)?
5. Có xoá cache của package manager sau khi install không (apt cache,
   npm cache) để giảm size layer cuối?
Đưa ra Dockerfile đã sửa, kèm giải thích từng thay đổi và ước tính
mức giảm size tương đối.

Ví dụ một cải tiến điển hình AI thường đề xuất, từ Dockerfile single-stage:

FROM node:20
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/server.js"]

sang bản multi-stage tối ưu cache và size:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json ./
USER node
CMD ["node", "dist/server.js"]

Những thay đổi đáng chú ý agent nên giải thích rõ: COPY package.json/package-lock.json trước để Docker cache layer npm ci khi source code đổi nhưng dependency không đổi; dùng npm ci thay npm install để build reproducible (build cho ra kết quả giống nhau mỗi lần); tách stage builder/runtime để image cuối không mang theo dev dependency và build tool; chạy với USER node (không phải root) để giảm rủi ro bảo mật.

Sau khi có Dockerfile mới, luôn để agent tự verify bằng cách build lại và so sánh size:

Build lại image với Dockerfile mới, tag "myapp:optimized", rồi so sánh
size với image "myapp:debug" (bản cũ). Chạy "docker history" cho cả
hai và chỉ ra layer nào giảm nhiều nhất.

Mẹo: Luôn yêu cầu agent verify bằng số liệu thật (docker images, docker history) sau khi tối ưu, không chỉ tin vào lời giải thích lý thuyết — có những Dockerfile "trông tối ưu" trên giấy nhưng do thứ tự layer sai vẫn không cache được gì trong CI thật.

Tips

Docker MCP trong Claude Code CLI và VS Code biến việc build-debug-optimize từ ba việc rời rạc tốn nhiều lệnh gõ tay thành một luồng hội thoại liên tục, nơi agent giữ context xuyên suốt. Trước khi đưa vào workflow hàng ngày, lưu ý các điểm sau:

  • Luôn dùng --progress=plain khi build để agent đọc log đủ chi tiết, tránh chẩn đoán sai vì log bị rút gọn.
  • Xác nhận resource limit và network mode trước khi kết luận bug là do code — rất nhiều bug "chỉ xảy ra trong container" thực chất là do config runtime.
  • Với mọi thay đổi Dockerfile do AI đề xuất, luôn build lại và so sánh size/cache thật, đừng chấp nhận giải thích lý thuyết suông.
  • Đồng bộ .mcp.json giữa CLI và VS Code extension để cả team có cùng trải nghiệm, tránh tình trạng "chạy được trên máy tôi" ngay ở tầng tooling AI.
  • Với exec_in_container, luôn giới hạn phạm vi lệnh agent được chạy (chỉ lệnh đọc như env, ps, nslookup) trừ khi bạn đang giám sát trực tiếp session đó.

Mẹo: Lưu lại các Dockerfile "trước/sau tối ưu" cùng phần giải thích của AI vào một file trong repo (ví dụ docs/dockerfile-optimization-log.md) — đây là tài liệu học tập cực tốt cho các dev mới trong team, và giúp bạn tránh lặp lại các câu hỏi tối ưu cơ bản mỗi lần có Dockerfile mới.