NVIDIA NemoClaw là một hệ thống điều phối agent mã nguồn mở, cấp doanh nghiệp, được xây dựng trên OpenClaw. Nó vận hành các AI agent bên trong môi trường sandbox với gateway tích hợp, bộ nhớ hội thoại bền vững, khung tool-use và cơ chế định tuyến đa mô hình, tất cả gói trong một Docker image được build trực tiếp từ source của NVIDIA.
GreenNode AgentBase là môi trường runtime container được quản lý trên GreenNode AI platform. Nó xử lý việc kéo image, health check, auto-scaling, tracking version và expose endpoint HTTPS, nên tôi không phải tự quản lý Kubernetes.
Nghe thì có vẻ đơn giản khi ghép hai thứ này lại với nhau. Thực tế thì không. Bài hướng dẫn này ghi lại chính xác những gì bị lỗi, vì sao lỗi, và cách fix cụ thể, để tôi có thể deploy NemoClaw lên GreenNode trơn tru trong một lượt.
Tôi viết từ góc nhìn của người vận hành. Thay vì một kiểu “hello world” chung chung, đây là đúng con đường tôi đi: từ lệnh docker build trên một máy Windows tới một endpoint đã có TLS, auto-scale, đặt trước một mô hình 27B tham số bên trong GreenNode.
Nếu bạn đang ở môi trường tương tự — network enterprise, private registry, health check chặt chẽ — các ràng buộc ở đây sẽ rất quen thuộc.
Chúng ta sẽ xây gì
Chúng ta sẽ deploy một runtime NemoClaw “thật” trên GreenNode AgentBase — build từ source chính thức của NVIDIA tại github.com/NVIDIA/NemoClaw, không dùng image dựng sẵn.
NemoClaw là hệ thống điều phối OpenClaw agent bảo mật của NVIDIA. Nó chạy các OpenClaw agent trong môi trường sandbox với gateway tích hợp, memory hội thoại và hỗ trợ nhiều mô hình.
Cuối cùng bạn sẽ có:
- Một endpoint HTTPS đang chạy NemoClaw
- NemoClaw sử dụng backend LLM MaaS của GreenNode (qwen3, llama, v.v.)
- Auto-scaling — GreenNode tự xử lý khi tải tăng
- Triển khai có version, có lịch sử, rollback được
Kết quả thực tế
Runtime nemoclaw-v2 đang ở trạng thái ACTIVE tại: https://endpoint-4d91a252-b1ab-4e61-9a4f-fa8cfb50e6c1.agentbase-runtime.aiplatform.vngcloud.vn
Kiến trúc tổng quan
Vấn đề kiến trúc chính là lệch port: GreenNode kiểm tra health trên port 8080, trong khi dashboard NemoClaw chạy trên port 18789. Giải pháp là một Bash wrapper mỏng, khởi động một HTTP server Python trên :8080 rồi mới chuyển quyền cho nemoclaw-start.
[Máy của bạn] [GreenNode Cloud]
git clone NVIDIA/NemoClaw ──► vCR Container Registry
Fix CRLF + BOM (Windows) ──► AgentBase Runtime (port 8080 ✓)
Thêm wrapper port 8080 ──► HTTPS Endpoint (auto-TLS)
docker build (56 stage) ──► MaaS LLM: qwen3-27b
docker push :v1, :v2 ...Những bẫy đã gặp (nên đọc trước khi bắt đầu)
Đây là 6 vấn đề từng làm deployment fail trong thực tế. Mỗi cái đều khá “im lặng” đủ để bạn mất hàng giờ nếu không biết trước. Các bước bên dưới đã tích hợp sẵn fix — bảng này là cheat sheet.
| # | Vấn đề | Khi nào xảy ra | Cách xử lý nhanh |
|---|---|---|---|
| 1 | Dòng CRLF | Khi build Docker hoặc khởi động container | Chạy vòng lặp PowerShell chuyển CRLF sang LF ở Bước 2a trước khi build. |
| 2 | BOM UTF-8 trong file mới | Build Docker, thường là lỗi SyntaxError ở dòng 1 | Dùng New-Object System.Text.UTF8Encoding($false) mỗi khi PowerShell ghi file. |
| 3 | NemoClaw dùng port 18789, GreenNode đòi 8080 | Runtime kẹt ở trạng thái ERROR dù đã pull image thành công | Thêm greennode-start.sh ở Bước 3. |
| 4 | GreenNode cache image theo tag | Image mới bị bỏ qua, code cũ vẫn chạy | Luôn push với tag mới như :v2 hoặc :v3. |
| 5 | Ô Image authentication không được tick | Failed to pull image ngay lần deploy đầu | Phải tick ô này — chỉ điền username và password là chưa đủ. |
| 6 | Password bị xoá mỗi lần mở trang Edit | Nút SAVE luôn bị mờ | Nhập lại password của robot vCR mỗi lần mở form Edit. |
Pitfall 1: Dòng CRLF
Trên Windows, Git thường để core.autocrlf=true nên tự động chuyển mọi \n thành \r\n khi clone. NemoClaw có hơn 1.810 script shell. Tất cả sẽ fail lúc runtime với lỗi:
env: 'bash\r': No such file or directoryCách xử lý: vòng lặp PowerShell ở Bước 2a sẽ loại hết ký tự carriage return trước khi build.
Pitfall 2: UTF-8 BOM
Mặc định, [System.Text.Encoding]::UTF8 của PowerShell sẽ thêm BOM (\xEF\xBB\xBF) vào đầu mọi file. Bash từ chối chạy script mà byte đầu tiên không phải #, và Node.js sẽ ném syntax error ở dòng 1.
Cách xử lý: dùng New-Object System.Text.UTF8Encoding($false).
Pitfall 3: Port 8080 vs 18789
Health checker của GreenNode luôn gọi port 8080 và chỉ đánh dấu runtime ACTIVE nếu nhận HTTP 200. Dashboard NemoClaw lại lắng nghe trên port 18789. Container vẫn start và chạy, nhưng GreenNode không thấy 200 trên port 8080, nên runtime bị chuyển sang ERROR.
Wrapper greennode-start.sh ở Bước 3 sẽ chạy một HTTP server Python nhỏ trên port 8080 rồi mới gọi nemoclaw-start. Health check pass, NemoClaw chạy bình thường.
Pitfall 4: Cache image theo tag
GreenNode cache Docker image theo tag. Nếu bạn push image mới lên tag :latest và update runtime, GreenNode có thể bỏ qua pull mới và tiếp tục dùng layer cache cũ.
Luôn tăng tag — ví dụ :v1 → :v2 → :v3 — và cập nhật lại Image URL trong form edit runtime cho khớp.
Pitfall 5: Ô Image authentication
Form Create/Edit Runtime có checkbox Image authentication và mặc định là không tick. Việc điền username và password không có tác dụng nếu checkbox này chưa bật.
Nếu bỏ qua, GreenNode sẽ pull image không dùng auth và fail với thông báo Failed to pull image.
Pitfall 6: Password bị xoá khi Edit
Mỗi lần mở trang Edit runtime, GreenNode sẽ xoá nội dung field password. Nút SAVE sẽ bị disable cho tới khi cả username và password đều có giá trị.
Kể cả khi bạn chỉ mở Edit để đổi tag image, vẫn bắt buộc nhập lại password.
Yêu cầu kỹ thuật cần chuẩn bị
- Tài khoản GreenNode — aiplatform.console.vngcloud.vn
- Docker Desktop đã cài trên máy.
- Git đã cài, và nắm rõ
core.autocrlftrên Windows. - Đã tạo repository trên vCR —
vcr.vngcloud.vn/YOUR-ORG/nemoclaw - Tài khoản robot trên vCR có quyền push/pull.
- API key GreenNode MaaS từ mục API Keys trong portal.
Quy trình triển khai từng bước
Đây là đúng chuỗi bước tôi dùng, từ một bản clone mới của repo NVIDIA đến khi runtime ACTIVE trên GreenNode. Làm lần lượt, bạn sẽ thấy cùng một kết quả.
Bước 1: Clone NVIDIA/NemoClaw
git clone https://github.com/NVIDIA/NemoClaw
cd NemoClawNgười dùng Windows nên đọc đoạn này trước. Git trên Windows thường để core.autocrlf=true, âm thầm chuyển toàn bộ \n thành \r\n trong mọi file. Image NemoClaw có hơn 1.800 script shell và file JavaScript. Nếu build với dòng CRLF, container sẽ fail với:
env: 'bash\r': No such file or directoryLuôn xử lý lại line endings trước khi build.
Bước 2: Sửa line endings và BOM (chỉ Windows)
Người dùng macOS và Linux có thể bỏ qua bước này.
2a. Chuyển toàn bộ file từ CRLF sang LF
Chạy script PowerShell này trong thư mục NemoClaw:
# Convert CRLF → LF across all text files
Get-ChildItem -Recurse -File | Where-Object {
$_.Extension -match '.(sh|js|ts|json|md|txt|yaml|yml|env|conf|cfg|ini|py|rb|pl)$' -or
$_.Name -notmatch '.'
} | ForEach-Object {
$content = [System.IO.File]::ReadAllText($_.FullName)
$fixed = $content.Replace("rn", "n").Replace("r", "`n")
if ($content -ne $fixed) {
[System.IO.File]::WriteAllText(
$_.FullName,
$fixed,
(New-Object System.Text.UTF8Encoding($false))
)
} }
Write-Host "Done"2b. Vì sao New-Object System.Text.UTF8Encoding($false) quan trọng
Writer UTF-8 mặc định của PowerShell sẽ thêm BOM. Kết quả là:
SyntaxError: Invalid or unexpected tokenngay dòng đầu trong các file JavaScript khi build Docker. Tham số $false tạo encoder UTF-8 không BOM.
Kiểm tra lại
# Kết quả phải là 0
$bytes = [System.IO.File]::ReadAllBytes("scripts\nemoclaw-start.sh")
($bytes | Where-Object { $_ -eq 13 }).CountBước 3: Thêm wrapper health check port 8080 cho GreenNode
GreenNode AgentBase chỉ đánh dấu runtime ACTIVE khi nhận được HTTP 200 trên port 8080. Dashboard NemoClaw thì chạy trên port 18789. Không có cầu nối, mọi lần deploy đều kết thúc bằng trạng thái ERROR.
Tạo file greennode-start.sh ở thư mục gốc repo NemoClaw:
#!/usr/bin/env bash
GreenNode AgentBase wrapper — bridges port 8080 health check to NemoClaw.
set -eu
echo "[greennode-start] Starting health server on :8080" >&2
cat > /tmp/greennode-health.py << 'PYEOF'
import http.server, threading, time
class Handler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'text/plain; charset=utf-8')
self.send_header('Connection', 'close')
self.end_headers()
self.wfile.write(b'NemoClaw OK\n')
def do_HEAD(self):
self.send_response(200)
self.send_header('Content-Type', 'text/plain; charset=utf-8')
self.send_header('Connection', 'close')
self.end_headers()
def log_message(self, fmt, *args):
pass
server = http.server.HTTPServer(('0.0.0.0', 8080), Handler)
threading.Thread(target=server.serve_forever, daemon=True).start()
print('[greennode-start] Health server ready on :8080', flush=True)
while True:
time.sleep(3600)
PYEOF
python3 /tmp/greennode-health.py &
_HEALTH_PID=$!
echo "[greennode-start] Health server PID: $_HEALTH_PID" >&2
sleep 1
/usr/local/bin/nemoclaw-start "$@" || {
echo "[greennode-start] nemoclaw-start exited — container kept alive for diagnostics" >&2
}
wait $_HEALTH_PIDTrên Windows, chuyển file này sang LF ngay sau khi lưu:
$f = "greennode-start.sh"
$content = [System.IO.File]::ReadAllText($f)
$fixed = $content.Replace("rn", "`n")
[System.IO.File]::WriteAllText($f, $fixed, (New-Object System.Text.UTF8Encoding($false)))Sau đó thêm đoạn này vào cuối Dockerfile:
# -- GreenNode AgentBase compatibility -------------------------------------
COPY greennode-start.sh /usr/local/bin/greennode-start
RUN chmod +x /usr/local/bin/greennode-start
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/greennode-start"]
CMD ["/bin/bash"]Dockerfile lúc này sẽ có hai dòng ENTRYPOINT, linter sẽ cảnh báo nhưng có thể bỏ qua — Docker luôn dùng ENTRYPOINT ở cuối.
Bước 4: Dựng Docker image
Dockerfile của NemoClaw là multi-stage build 56 stage, dựa trên ghcr.io/nvidia/nemoclaw/sandbox-base:latest. Lần build đầu tiên thường mất 30–45 phút. Các lần sau nếu tận dụng cache layer sẽ khoảng 2–5 phút.
# Windows PowerShell
docker build `
--build-arg NEMOCLAW_MODEL=qwen/qwen3-5-27b `
--build-arg NEMOCLAW_INFERENCE_BASE_URL=https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1 `
--build-arg NEMOCLAW_INFERENCE_API=openai-completions `
--build-arg NEMOCLAW_DISABLE_DEVICE_AUTH=1 `
-t vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v1 `
. 2>&1 | Tee-Object -FilePath docker-build.log
macOS / Linux
docker build
--build-arg NEMOCLAW_MODEL=qwen/qwen3-5-27b
--build-arg NEMOCLAW_INFERENCE_BASE_URL=https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1
--build-arg NEMOCLAW_INFERENCE_API=openai-completions
--build-arg NEMOCLAW_DISABLE_DEVICE_AUTH=1
-t vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v1
. 2>&1 | tee docker-build.log| Tham số | Giá trị | Ghi chú |
|---|---|---|
NEMOCLAW_MODEL | qwen/qwen3-5-27b | Hoặc bất kỳ model MaaS nào của GreenNode. |
NEMOCLAW_INFERENCE_BASE_URL | https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1 | Endpoint MaaS của GreenNode. |
NEMOCLAW_INFERENCE_API | openai-completions | Dùng cho endpoint tương thích OpenAI. |
NEMOCLAW_DISABLE_DEVICE_AUTH | 1 | Bỏ bước pair device trong môi trường headless/cloud. |
Kiểm tra kết quả build
#56 naming to vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v1 done
#56 DONE 2.3sNếu build fail, kiểm tra docker-build.log xem có lỗi liên quan tới CRLF hoặc BOM.
Bước 5: Đăng nhập vCR và push
docker login vcr.vngcloud.vn
--username YOUR-ROBOT-ACCOUNT
--password YOUR-ROBOT-PASSWORD
docker push vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v1Ghi lại digest từ output của lệnh push — bạn sẽ cần nó để đối chiếu các lần redeploy.
v1: digest: sha256:b2aa855806643cabfbef0f08e1450e3d2e2350f9078056f00ec60ee3f03ab7f5 size: 857Luôn dùng tag version cụ thể như :v1, :v2, :v3 — đừng chỉ dựa vào :latest.
Bước 6: Deploy lên GreenNode AgentBase
6a. Vào mục Agent Runtime
https://aiplatform.console.vngcloud.vn/agent-runtime
Bấm Deploy a new Agent → Custom Agent.
6b. Điền form runtime
| Trường | Giá trị |
|---|---|
| Agent runtime name | nemoclaw-v2 (hoặc tên bạn chọn) |
| Image URL | vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v1 |
| Flavor | runtime-s2-general-2x4 (2 CPU, 4 GB — mức tối thiểu khuyến nghị) |
| Min/Max replicas | 1 / 1 |
6c. Quan trọng: bật Image authentication
Đây là chỗ dễ fail nhất. Form có ô Image authentication mặc định không tick. Kể cả khi điền username và password, GreenNode vẫn không dùng nếu bạn không tick ô này.
Sau khi tick, điền:
- Username: tên tài khoản robot trên vCR.
- Password: mật khẩu robot trên vCR.
6d. Thêm biến môi trường
| Key | Giá trị |
|---|---|
LLM_API_KEY | API key MaaS của bạn trên GreenNode |
OPENSHELL_SANDBOX | 1 |
6e. Lưu và xác nhận
Bấm SAVE, sau đó Confirm trong hộp thoại xác nhận.
Bước 7: Quan sát runtime chuyển sang ACTIVE
Sau khi lưu, runtime sẽ vào trạng thái UPDATING trong lúc GreenNode:
- Kéo image từ vCR (lần đầu có thể mất 3–5 phút).
- Khởi động container.
- Gọi health check HTTP trên port 8080.
- Nếu nhận HTTP 200, runtime chuyển sang ACTIVE.
Refresh trang chi tiết runtime khoảng 30 giây một lần. Trạng thái thường đi theo chuỗi:
UPDATING → ACTIVE
UPDATING → ERROR
| Trường | Giá trị |
|---|---|
| Runtime status | ACTIVE |
| Endpoint status | ACTIVE |
| Associated version | Version 4, hoặc version hiện tại của bạn |
| Endpoint URL | https://endpoint-xxx.agentbase-runtime.aiplatform.vngcloud.vn |
Bước 8: Test endpoint
Health check
curl https://endpoint-4d91a252-b1ab-4e61-9a4f-fa8cfb50e6c1.agentbase-runtime.aiplatform.vngcloud.vn
Kỳ vọng: HTTP 200, body: "NemoClaw OK"Bạn cũng có thể mở endpoint trực tiếp trên trình duyệt và kỳ vọng thấy chuỗi NemoClaw OK.
Cập nhật deployment
Khi bạn push image mới (sửa bug, đổi model hoặc thay config):
docker build ... -t vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v2 .
docker push vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v2Sau đó, trên GreenNode:
- Bấm Edit trên runtime.
- Đổi Image URL từ
:v1sang:v2. - Nhập lại password registry.
- Đảm bảo ô Image authentication vẫn đang bật.
- Bấm SAVE → Confirm.
Mỗi lần chỉnh sửa sẽ tạo ra một Version được đánh số trong tab Version, cho bạn lịch sử đầy đủ để rollback.
Xử lý sự cố
Failed to pull image
Nguyên nhân: Ô Image authentication chưa được tick.
Cách xử lý: Edit runtime, tick lại checkbox, nhập password, rồi lưu.
env: 'bash\r': No such file or directory
Nguyên nhân: Script shell vẫn còn line ending CRLF của Windows.
Cách xử lý: Chạy lại bước chuyển CRLF → LF ở Bước 2a rồi build lại.
SyntaxError: Invalid or unexpected token ở dòng 1 file .js
Nguyên nhân: PowerShell ghi file với UTF-8 có BOM.
Cách xử lý: Dùng New-Object System.Text.UTF8Encoding($false) như Bước 2b, rồi build lại.
Runtime chuyển từ UPDATING sang ERROR sau khi pull image
Nguyên nhân: Container fail health check trên port 8080.
Cách xử lý: Đảm bảo đã thêm greennode-start.sh vào Dockerfile và test local:
docker run --rm -p 8080:8080 vcr.vngcloud.vn/YOUR-ORG/nemoclaw:v1
Trong terminal khác:
curl http://localhost:8080
Kỳ vọng: trả về "NemoClaw OK"Runtime vẫn ERROR sau khi push image mới với tag :latest
Nguyên nhân: GreenNode cache image cũ của :latest và không pull lại.
Cách xử lý: Push với tag mới và cập nhật Image URL trong form edit runtime.
Nút SAVE vẫn mờ ở màn hình Edit runtime
Nguyên nhân: Field password rỗng (bị xoá mỗi lần tải lại trang).
Cách xử lý: Nhập lại password tài khoản robot vCR. Khi cả username và password đều có, nút SAVE sẽ sáng.
Mỗi Version chứa gì
| Version | Mô tả | Trạng thái |
|---|---|---|
| Version 1 | Deploy lần đầu, image :latest gốc, chưa fix port 8080 | ERROR |
| Version 2 | Image đã fix LF, nhưng chưa có wrapper port 8080 | ERROR |
| Version 3 | Đã thêm wrapper cho port 8080 | ERROR do vẫn dùng image cache cũ |
| Version 4 | Ép GreenNode pull image mới bằng tag :v3 | ACTIVE |
Các thông số chính
| Mục | Giá trị |
|---|---|
| Source repo | github.com/NVIDIA/NemoClaw |
| Số stage Dockerfile | 56 (54 cho NemoClaw + 2 cho wrapper GreenNode) |
| Thời gian build đầu tiên | ~30–45 phút |
| Build lại có cache | ~2–5 phút |
| Image trên vCR | vcr.vngcloud.vn/92566-openclaw-agent/nemoclaw:v3 |
| Image digest | sha256:b2aa855806643cabfbef0f08e1450e3d2e2350f9078056f00ec60ee3f03ab7f5 |
| Runtime ID | runtime-215aae39-b097-4ba4-ad6a-1547e9287eb1 |
| Endpoint | https://endpoint-4d91a252-b1ab-4e61-9a4f-fa8cfb50e6c1.agentbase-runtime.aiplatform.vngcloud.vn |
| LLM | qwen/qwen3-5-27b thông qua GreenNode MaaS |
| Flavor | runtime-s2-general-2×4 (2 CPU, 4 GB RAM) |
Build ngày 2026-06-09. Runtime nemoclaw-v2, Version 4.
Từ Endpoint HTTPS đến một trợ lý thực sự
Tới thời điểm này, NemoClaw thực sự đã chạy trên GreenNode AgentBase. Runtime nemoclaw-v2 đang ACTIVE, endpoint HTTPS đã up, qwen3-27b được nối qua GreenNode MaaS. Sáu cái bẫy ban đầu — từ CRLF âm thầm phá hỏng hơn 1.800 script tới ô auth tí hon chặn image pull mà không log gì rõ ràng — đều đã xử lý xong. Nhưng chỉ một endpoint HTTPS trần thì vẫn chưa phải là một AI assistant. Để NemoClaw thực sự trả lời ai đó, nó cần một lớp giao tiếp.
Phần 2 sẽ xây chính lớp đó: một Telegram bridge chạy như một runtime AgentBase riêng — nhận message từ Telegram, gọi trực tiếp LLM MaaS của GreenNode, rồi gửi câu trả lời về. Bạn sẽ thấy vì sao bridge buộc phải là một runtime tách biệt (proxy outbound của flavor 2×4 chặn kết nối tới Telegram), cách đăng ký webhook để Telegram chủ động push update thay vì bridge phải poll, và tám cái bẫy mới chỉ xuất hiện ở giai đoạn này.



