nemoclaw-setup

$npx mdskill add jezweb/claude-skills/nemoclaw-setup

Install and configure NVIDIA NemoClaw sandboxed agent platform on Linux.

  • Sets up sandboxed AI agents with Landlock, seccomp, and network isolation.
  • Depends on Docker, Node.js 20+, and optional NVIDIA GPU and API key.
  • Checks prerequisites, then runs automated install and configuration steps.
  • Delivers a working NemoClaw instance with web UI, CLI, and optional remote tunnel.

SKILL.md

.github/skills/nemoclaw-setupView on GitHub ↗
---
name: nemoclaw-setup
description: "Install and configure NVIDIA NemoClaw (sandboxed OpenClaw agent platform) on Linux. Handles cloudflared tunnels, Docker cgroup fixes, OpenShell, sandbox creation, remote access via Cloudflare Tunnel, and known bug workarounds. Use whenever the user mentions installing NemoClaw, setting up OpenClaw, configuring an NVIDIA Spark or DGX for sandboxed agents, or troubleshooting NemoClaw deployment."
compatibility: claude-code-only
---

# NemoClaw Setup

Install NVIDIA NemoClaw — a sandboxed AI agent platform built on OpenClaw with Landlock + seccomp + network namespace isolation. Runs inside Docker via k3s (OpenShell).

## What You Get

- Sandboxed AI agent with web UI and terminal CLI
- Powered by NVIDIA Nemotron models (cloud or local)
- Network-policy-controlled access to external services
- Optional remote access via Cloudflare Tunnel

## Prerequisites

| Requirement | Check | Install |
|-------------|-------|---------|
| Linux (Ubuntu 22.04+) | `uname -a` | — |
| Docker | `docker ps` | `sudo apt install docker.io` |
| Node.js 20+ (22 recommended) | `node --version` | `nvm install 22` |
| NVIDIA GPU (optional but recommended) | `nvidia-smi` | — |
| NVIDIA API key | — | https://build.nvidia.com/settings/api-keys |

## Workflow

### Step 1: Pre-flight Checks

```bash
# Check Docker
docker ps 2>/dev/null || echo "Docker not running or no access"

# Check Node.js
node --version

# Check if already installed
which nemoclaw && nemoclaw --version
which openshell && openshell --version
```

If `nemoclaw` is already installed, skip to Step 4.

### Step 2: Install NemoClaw

```bash
curl -fsSL https://nvidia.com/nemoclaw.sh | bash
```

This installs NemoClaw and OpenClaw via npm globally (to `~/.npm-global/bin/`).

**If the installer can't find Node.js**, install it first:
```bash
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
```

### Step 3: Install OpenShell

```bash
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
```

Installs to `~/.local/bin/openshell`.

### Step 4: Fix Docker Permissions and cgroup

**Docker group** — the user must be in the `docker` group:
```bash
sudo usermod -aG docker $USER
newgrp docker
# or log out and back in
```

**cgroup v2 fix** — required for k3s inside Docker:
```bash
# Check if needed
grep cgroup2 /proc/filesystems && echo "cgroup v2 detected — fix needed"

# Apply fix (needs sudo)
sudo $HOME/.npm-global/bin/nemoclaw setup-spark
```

This adds `"default-cgroupns-mode": "host"` to `/etc/docker/daemon.json` and restarts Docker.

**IMPORTANT**: The `nemoclaw setup-spark` command also asks for an NVIDIA API key. Have it ready (starts with `nvapi-`). Get one at https://build.nvidia.com/settings/api-keys.

### Step 5: Run Onboarding

```bash
PATH=$HOME/.npm-global/bin:$HOME/.local/bin:$PATH nemoclaw onboard
```

The interactive wizard will:
1. Check Docker and OpenShell
2. Start the OpenShell gateway (k3s in Docker)
3. Ask for a sandbox name — use `claw` or any name
4. Configure the NVIDIA API key
5. Set up inference (Nemotron 3 Super 120B via cloud API)
6. Launch OpenClaw inside the sandbox
7. Apply network policy presets — select the ones you need

**Common port conflict**: If port 8080 is in use, find and kill the process:
```bash
fuser -k 8080/tcp
```

### Step 6: Verify

```bash
# Check sandbox is running
PATH=$HOME/.npm-global/bin:$HOME/.local/bin:$PATH nemoclaw claw status

# Connect via terminal
PATH=$HOME/.npm-global/bin:$HOME/.local/bin:$PATH nemoclaw claw connect
```

### Step 7: Set Up Web UI Access

The web UI runs inside the sandbox and needs a port forward:

```bash
PATH=$HOME/.npm-global/bin:$HOME/.local/bin:$PATH openshell forward start 18789 claw
```

Then open: `http://127.0.0.1:18789/`

**Known bug (OpenClaw ≤ v2026.3.11)**: "device identity required" error. Workaround — append the gateway token to the URL:

```bash
# Get the token
ssh -F /tmp/nemoclaw-ssh-config openshell-claw \
  "python3 -c \"import json; print(json.load(open('/sandbox/.openclaw/openclaw.json'))['gateway']['auth']['token'])\""
```

Then visit: `http://127.0.0.1:18789/#token=<gateway-token>`

**Fix**: Update to OpenClaw v2026.3.12+ (see Updating section below).

### Step 8: Make the Port Forward Persistent

Create a health-checked keepalive script:

```bash
cat > ~/.local/bin/nemoclaw-keepalive.sh << 'KEEPALIVE'
#!/bin/bash
export PATH="$HOME/.npm-global/bin:$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin"
cleanup() { kill %1 2>/dev/null; exit 0; }
trap cleanup SIGTERM SIGINT
while true; do
    fuser -k 18789/tcp 2>/dev/null; sleep 1
    openshell forward start 18789 claw &
    FORWARD_PID=$!; sleep 3
    while kill -0 $FORWARD_PID 2>/dev/null; do
        if ! curl -sf -o /dev/null --connect-timeout 3 http://127.0.0.1:18789/ 2>/dev/null; then
            echo "$(date): Health check failed, restarting..."
            kill $FORWARD_PID 2>/dev/null; wait $FORWARD_PID 2>/dev/null; break
        fi
        sleep 10
    done
    echo "$(date): Forward died, restarting in 3s..."; sleep 3
done
KEEPALIVE
chmod +x ~/.local/bin/nemoclaw-keepalive.sh
```

Create the systemd service:

```bash
sudo tee /etc/systemd/system/nemoclaw-forward.service << 'SERVICE'
[Unit]
Description=NemoClaw Port Forward with Health Check
After=docker.service
Requires=docker.service

[Service]
Type=simple
User=$USER
Group=docker
Environment=PATH=/home/$USER/.npm-global/bin:/home/$USER/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/home/$USER/.local/bin/nemoclaw-keepalive.sh
Restart=always
RestartSec=5
KillMode=control-group

[Install]
WantedBy=multi-user.target
SERVICE

sudo systemctl daemon-reload
sudo systemctl enable nemoclaw-forward
sudo systemctl start nemoclaw-forward
```

### Step 9: Remote Access via Cloudflare Tunnel (Optional)

If you have a Cloudflare Tunnel already running, add NemoClaw to it.

**Add DNS route:**
```bash
cloudflared tunnel route dns <tunnel-name> nemoclaw.<domain>
```

**Update tunnel config** (`/etc/cloudflared/config.yml`):
```yaml
  - hostname: nemoclaw.<domain>
    service: http://localhost:18789
    originRequest:
      httpHostHeader: "127.0.0.1:18789"
```

**Restart tunnel:**
```bash
sudo systemctl restart cloudflared
```

**Update sandbox allowed origins** — SSH into the sandbox and add your domain:

```bash
openshell sandbox ssh-config claw > /tmp/nemoclaw-ssh-config

ssh -F /tmp/nemoclaw-ssh-config openshell-claw 'python3 -c "
import json
with open(\"/sandbox/.openclaw/openclaw.json\") as f:
    config = json.load(f)
config[\"gateway\"][\"controlUi\"][\"allowedOrigins\"].append(\"https://nemoclaw.<domain>\")
config[\"gateway\"][\"trustedProxies\"] = [\"127.0.0.1\", \"::1\", \"172.0.0.0/8\", \"10.0.0.0/8\"]
config[\"gateway\"][\"allowRealIpFallback\"] = True
with open(\"/sandbox/.openclaw/openclaw.json\", \"w\") as f:
    json.dump(config, f, indent=2)
print(\"Done. Token:\", config[\"gateway\"][\"auth\"][\"token\"])
"'
```

**Protect with Cloudflare Access** — add the hostname to your Access application in the Zero Trust dashboard.

**Access URL**: `https://nemoclaw.<domain>/#token=<gateway-token>`

### Step 10: Install Custom Skills

Skills are markdown files in `/sandbox/.openclaw/skills/<name>/SKILL.md`. SSH into the sandbox to create them:

```bash
ssh -F /tmp/nemoclaw-ssh-config openshell-claw
mkdir -p /sandbox/.openclaw/skills/my-skill
cat > /sandbox/.openclaw/skills/my-skill/SKILL.md << 'EOF'
---
name: my-skill
description: What this skill does.
tools: [exec, read, write]
---
# My Skill
Instructions for the agent...
EOF
```

Verify with: `openclaw skills list`

### Step 11: Configure the Workspace

Update the workspace files so the agent knows who you are:

- `/sandbox/.openclaw/workspace/USER.md` — your profile, preferences
- `/sandbox/.openclaw/workspace/TOOLS.md` — available tools and access
- `/sandbox/.openclaw/workspace/SOUL.md` — agent personality and behaviour

## Updating OpenClaw

The sandbox bundles OpenClaw at install time. To update:

```bash
# 1. Update host-side packages
npm install -g openclaw@latest

# 2. Destroy and recreate sandbox
nemoclaw claw destroy
nemoclaw onboard

# 3. Reconfigure remote access (Step 9) and skills (Step 10)
```

**Note**: Sandbox network policies block npm/PyPI inside the sandbox. Updates must be done by rebuilding.

## Troubleshooting

| Issue | Cause | Fix |
|-------|-------|-----|
| `Docker is not running` | Docker service stopped or user not in docker group | `sudo systemctl start docker` then `newgrp docker` |
| `cgroup v2 detected` | Docker not configured for cgroupns=host | `sudo nemoclaw setup-spark` |
| Port 8080 in use | Another service on that port | `fuser -k 8080/tcp` |
| `nemoclaw: command not found` | Not in PATH | `PATH=$HOME/.npm-global/bin:$HOME/.local/bin:$PATH` |
| `device identity required` | Bug in OpenClaw ≤ v2026.3.11 | Append `#token=<gateway-token>` to URL, or update to v2026.3.12+ |
| `gateway token mismatch` | Token changed after sandbox rebuild | Get new token from sandbox config |
| `too many failed auth attempts` | Rate limited from old token attempts | Restart gateway: `ssh -F /tmp/nemoclaw-ssh-config openshell-claw 'pkill -f "openclaw gateway"; sleep 2; openclaw gateway &'` |
| `origin not allowed` | Domain not in allowedOrigins | Add to `gateway.controlUi.allowedOrigins` in sandbox config |
| Port 18789 not responding | SSH tunnel died | `sudo systemctl restart nemoclaw-forward` (auto-recovers within 13s) |
| npm 403 Forbidden inside sandbox | Network policy blocking TLS | Cannot install packages inside sandbox — rebuild instead |
| `Tunnel not found` on DNS route | Wrong Cloudflare account/cert | Check `cloudflared tunnel list` matches your cert |
| Error 502 on Cloudflare | Tunnel connections dropped | `sudo systemctl restart cloudflared` |
| Assets 404 via Cloudflare | Browser not authenticated for sub-requests | Hard refresh (Ctrl+Shift+R) after Cloudflare Access login |

## Architecture

```
Docker (openshell-cluster-<name>)
  └─ k3s cluster
      ├─ NVIDIA device plugin
      └─ OpenShell sandbox
          ├─ OpenClaw agent
          ├─ NemoClaw plugin
          ├─ Gateway (WebSocket + REST)
          └─ Workspace (SOUL.md, USER.md, TOOLS.md, skills/)

Port forward (systemd): localhost:18789 ←SSH tunnel→ sandbox:18789
Cloudflare Tunnel (optional): nemoclaw.domain → localhost:18789
```

## References

- [NemoClaw GitHub](https://github.com/NVIDIA/NemoClaw)
- [OpenShell GitHub](https://github.com/NVIDIA/OpenShell)
- [OpenClaw docs](https://docs.openclaw.ai)
- [NemoClaw quickstart](https://docs.nvidia.com/nemoclaw/latest/get-started/quickstart.html)
- [awesome-nemoclaw presets](https://github.com/VoltAgent/awesome-nemoclaw)
- [awesome-openclaw-skills](https://github.com/VoltAgent/awesome-openclaw-skills)
- [device auth bug fix](https://github.com/openclaw/openclaw/issues/43909)

More from jezweb/claude-skills

SkillDescription
ai-image-generatorGenerate AI images using Gemini or GPT APIs directly. Covers model selection (Gemini for scenes; GPT Image 2 for text rendering, batch variations, multi-reference compositing; GPT Image 1.5 for transparent icons), the 5-part prompting framework, API calling patterns, multi-turn editing, and quality assurance. Produces photorealistic scenes, icons, illustrations, OG images, posters, infographics, and product shots. Use when building websites that need images, creating marketing assets, or generating visual content. Triggers: 'generate image', 'ai image', 'create hero image', 'make an icon', 'generate illustration', 'create og image', 'poster', 'infographic', 'image variations', 'gpt-image-2', 'ai art', 'image generation'.
app-docsGenerate complete user documentation for a web app with screenshots. Browses the app via browser automation, screenshots every screen, and produces a structured user guide with step-by-step instructions, annotated screenshots, workflow diagrams, and reference tables. Supports quick (key screens), standard (all pages), thorough (every state and flow), and exhaustive (publishable documentation suite). Triggers: 'document the app', 'user guide', 'app documentation', 'screenshot docs', 'generate user docs', 'help docs', 'how-to guide', 'write the docs'.
aussie-business-englishAustralian business English for professional writing — warm, direct, EN-AU spelling (colour, organise, centre), no filler words. Use whenever the user is writing for an Australian audience: emails, chat messages, proposals, client communications, blog posts, web copy, or any business writing. Apply to drafting, editing, and tone-checking professional text.
award-applicationWrite compelling award submissions, grant applications, and competition entries. Maps achievements to selection criteria using evidence-based narratives. Use whenever the user is applying for a business award (Telstra, chamber of commerce, industry awards), a grant, a competition, or any submission demonstrating merit against defined criteria.
cloudflare-apiHit the Cloudflare REST API directly for operations that wrangler and MCP can't handle well. Bulk DNS, custom hostnames, email routing, cache purge, WAF rules, redirect rules, zone settings, Worker routes, D1 cross-database queries, R2 bulk operations, KV bulk read/write, Vectorize queries, Queues, and fleet-wide resource audits. Produces curl commands or scripts. Triggers: 'cloudflare api', 'bulk dns', 'custom hostname', 'email routing', 'cache purge', 'waf rule', 'd1 query', 'r2 bucket', 'kv bulk', 'vectorize query', 'audit resources', 'fleet operation'.
cloudflare-worker-builderScaffold and deploy Cloudflare Workers with Hono routing, Vite plugin, and Static Assets. Describe project, scaffold structure, configure bindings, deploy. Use whenever the user wants to create a Worker project, set up Hono on Cloudflare, configure D1 / R2 / KV / Queues bindings, or troubleshoot Worker export syntax, API route conflicts, HMR issues, or deployment failures.
codex-reviewRun an independent code review using the OpenAI Codex CLI in headless mode. Gets a second opinion from a different model family (the current Codex models) on recent changes, a PR, a commit, or the whole app — covering bugs, regressions, security, data consistency, UX/state bugs, performance risks, and testing gaps. Saves a severity-prioritised report to .jez/reviews/. Triggers: 'codex review', 'review with codex', 'independent code review', 'what does codex think', 'get codex to review'.
color-paletteGenerate complete, accessible colour palettes from a single brand hex. Produces 11-shade scale (50-950), semantic tokens, dark mode variants, Tailwind v4 CSS output, WCAG contrast checks. Use whenever the user supplies a brand hex and asks for a palette, mentions setting up a design system, wants Tailwind theme colours from a brand colour, or asks to check colour accessibility / contrast.
d1-drizzle-schemaGenerate Drizzle ORM schemas for Cloudflare D1 databases with correct D1-specific patterns. Produces schema files, migration commands, type exports, and DATABASE_SCHEMA.md documentation. Handles D1 quirks: foreign keys always enforced, no native BOOLEAN/DATETIME types, 100 bound parameter limit, JSON stored as TEXT. Use when creating a new database, adding tables, or scaffolding a D1 data layer.
d1-migrationCloudflare D1 migration workflow: generate with Drizzle, inspect SQL for gotchas, apply to local and remote, fix stuck migrations, handle partial failures. Use when running migrations, fixing migration errors, or setting up D1 schemas.