Skill 寫法圖鑑

nemoclaw-setup

jezweb | 雲端與基礎設施 | 原文 | MIT

在 Linux 安裝設定 NVIDIA NemoClaw 沙箱 agent 並開遠端存取

中文翻譯

---
name: nemoclaw-setup
description: "在 Linux 上安裝並設定 NVIDIA NemoClaw(沙箱化的 OpenClaw agent 平台)。處理 cloudflared tunnel、Docker cgroup 修正、OpenShell、建立沙箱、透過 Cloudflare Tunnel 遠端存取,以及已知 bug 的暫時解法。只要使用者提到要安裝 NemoClaw、設定 OpenClaw、為沙箱化 agent 設定 NVIDIA Spark 或 DGX,或排查 NemoClaw 部署問題,就用這個 skill。"
compatibility: claude-code-only
---

# NemoClaw Setup

安裝 NVIDIA NemoClaw,一個建立在 OpenClaw 上的沙箱化 AI agent 平台,使用 Landlock + seccomp + network namespace 隔離。透過 k3s(OpenShell)在 Docker 裡執行。

## 你會得到什麼

- 沙箱化的 AI agent,有網頁 UI 和終端機 CLI
- 由 NVIDIA Nemotron 模型驅動(雲端或本機)
- 由 network policy 控管對外部服務的存取
- 可選用 Cloudflare Tunnel 做遠端存取

## 前置條件

| 需求 | 檢查 | 安裝 |
|-------------|-------|---------|
| Linux(Ubuntu 22.04+) | `uname -a` | — |
| Docker | `docker ps` | `sudo apt install docker.io` |
| Node.js 20+(建議 22) | `node --version` | `nvm install 22` |
| NVIDIA GPU(選用,但建議有) | `nvidia-smi` | — |
| NVIDIA API key | — | https://build.nvidia.com/settings/api-keys |

## 工作流程

### 步驟 1:事前檢查

```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
```

如果 `nemoclaw` 已經裝好了,跳到步驟 4。

### 步驟 2:安裝 NemoClaw

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

這會用 npm 全域安裝 NemoClaw 和 OpenClaw(裝到 `~/.npm-global/bin/`)。

**如果安裝程式找不到 Node.js**,先裝它:
```bash
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
```

### 步驟 3:安裝 OpenShell

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

會裝到 `~/.local/bin/openshell`。

### 步驟 4:修正 Docker 權限和 cgroup

**Docker 群組**:使用者必須在 `docker` 群組裡:
```bash
sudo usermod -aG docker $USER
newgrp docker
# or log out and back in
```

**cgroup v2 修正**:Docker 裡跑 k3s 需要這個:
```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
```

這會在 `/etc/docker/daemon.json` 加上 `"default-cgroupns-mode": "host"`,並重啟 Docker。

**重要**:`nemoclaw setup-spark` 指令也會要求 NVIDIA API key。先準備好(以 `nvapi-` 開頭)。到 https://build.nvidia.com/settings/api-keys 取得。

### 步驟 5:執行 Onboarding

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

互動式精靈會:
1. 檢查 Docker 和 OpenShell
2. 啟動 OpenShell gateway(Docker 裡的 k3s)
3. 詢問沙箱名稱,用 `claw` 或任何名稱
4. 設定 NVIDIA API key
5. 設定推論(透過雲端 API 使用 Nemotron 3 Super 120B)
6. 在沙箱裡啟動 OpenClaw
7. 套用 network policy 預設,選你需要的

**常見的 port 衝突**:如果 8080 port 被占用,找出並結束那個 process:
```bash
fuser -k 8080/tcp
```

### 步驟 6:驗證

```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
```

### 步驟 7:設定網頁 UI 存取

網頁 UI 跑在沙箱裡面,需要做 port forward:

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

然後打開:`http://127.0.0.1:18789/`

**已知 bug(OpenClaw ≤ v2026.3.11)**:出現「device identity required」錯誤。暫時解法是把 gateway token 附加到 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'])\""
```

然後前往:`http://127.0.0.1:18789/#token=<gateway-token>`

**修法**:更新到 OpenClaw v2026.3.12 以上(見下方更新一節)。

### 步驟 8:讓 Port Forward 持續運作

建立一個有健康檢查的 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
```

建立 systemd 服務:

```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
```

### 步驟 9:透過 Cloudflare Tunnel 遠端存取(選用)

如果你已經有在跑的 Cloudflare Tunnel,把 NemoClaw 加進去。

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

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

**重啟 tunnel:**
```bash
sudo systemctl restart cloudflared
```

**更新沙箱允許的 origin**:SSH 進沙箱,把你的網域加進去:

```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\"])
"'
```

**用 Cloudflare Access 保護**:到 Zero Trust dashboard,把這個 hostname 加進你的 Access application。

**存取網址**:`https://nemoclaw.<domain>/#token=<gateway-token>`

### 步驟 10:安裝自訂 Skill

Skill 是放在 `/sandbox/.openclaw/skills/<name>/SKILL.md` 的 markdown 檔。SSH 進沙箱來建立:

```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
```

用這個驗證:`openclaw skills list`

### 步驟 11:設定 Workspace

更新 workspace 檔案,讓 agent 知道你是誰:

- `/sandbox/.openclaw/workspace/USER.md`:你的個人資料、偏好
- `/sandbox/.openclaw/workspace/TOOLS.md`:可用的工具與存取權限
- `/sandbox/.openclaw/workspace/SOUL.md`:agent 的個性與行為

## 更新 OpenClaw

沙箱在安裝時就綁定了 OpenClaw。要更新的話:

```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)
```

**注意**:沙箱的 network policy 會擋掉沙箱裡的 npm/PyPI。更新只能靠重建。

## 疑難排解

| 問題 | 原因 | 修法 |
|-------|-------|-----|
| `Docker is not running` | Docker 服務停了,或使用者不在 docker 群組 | `sudo systemctl start docker` 然後 `newgrp docker` |
| `cgroup v2 detected` | Docker 沒設成 cgroupns=host | `sudo nemoclaw setup-spark` |
| Port 8080 被占用 | 別的服務在用那個 port | `fuser -k 8080/tcp` |
| `nemoclaw: command not found` | 不在 PATH 裡 | `PATH=$HOME/.npm-global/bin:$HOME/.local/bin:$PATH` |
| `device identity required` | OpenClaw ≤ v2026.3.11 的 bug | 在 URL 後面加 `#token=<gateway-token>`,或更新到 v2026.3.12+ |
| `gateway token mismatch` | 沙箱重建後 token 變了 | 從沙箱設定取得新的 token |
| `too many failed auth attempts` | 用舊 token 一直嘗試而被限流 | 重啟 gateway:`ssh -F /tmp/nemoclaw-ssh-config openshell-claw 'pkill -f "openclaw gateway"; sleep 2; openclaw gateway &'` |
| `origin not allowed` | 網域不在 allowedOrigins 裡 | 把它加進沙箱設定裡的 `gateway.controlUi.allowedOrigins` |
| Port 18789 沒回應 | SSH tunnel 斷了 | `sudo systemctl restart nemoclaw-forward`(13 秒內會自動恢復) |
| 沙箱裡 npm 403 Forbidden | Network policy 擋了 TLS | 沙箱裡不能安裝套件,改用重建 |
| DNS route 出現 `Tunnel not found` | Cloudflare 帳號/憑證不對 | 檢查 `cloudflared tunnel list` 是否和你的憑證相符 |
| Cloudflare 上出現 502 | Tunnel 連線斷了 | `sudo systemctl restart cloudflared` |
| 透過 Cloudflare 時資源 404 | 瀏覽器對子請求還沒通過認證 | Cloudflare Access 登入後強制重新整理(Ctrl+Shift+R) |

## 架構

```
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
```

## 參考資料

- [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)

英文原文

---
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)