NemoClaw / OpenShell Jetson AGX Orin, Orin Super Nano and Orin NX

NemoClaw on Jetson Orin Family – Setup Guide

System Info

Component Version
Board NVIDIA Jetson Orin
JetPack 6.2.2 (L4T R36.5.0)
Kernel 5.15.185-tegra
OS Ubuntu 22.04.5 LTS (aarch64)
Docker with iptables-legacy needed
OpenShell 0.0.13
Node.js v22.22.1

Problems Encountered

The stock NemoClaw installer (curl -fsSL ``https://www.nvidia.com/nemoclaw.sh`` | bash)
hits three issues on Jetson Orin that must be fixed before running it.

Problem 1: iptables nf_tables not supported by Tegra kernel

The OpenShell cluster image uses iptables v1.8.10 (nf_tables) by default.
The Tegra 5.15 kernel does not have full nf_tables support, causing k3s (inside
the cluster container) to panic:

iptables v1.8.10 (nf_tables): RULE_INSERT failed (No such file or directory)
Extension conntrack revision 0 not supported, missing kernel module?

Fix: Patch the cluster image to use iptables-legacy before running the installer.

Problem 2: br_netfilter kernel module not loaded

Without br_netfilter, bridged pod-to-pod traffic inside k3s bypasses iptables.
This breaks Kubernetes ClusterIP service routing, specifically DNS resolution.
The sandbox pod crashes in a loop with:

failed to connect to OpenShell server: dns error: Temporary failure in name resolution

Root cause: DNAT rewrites the destination on outbound packets, but without
br_netfilter, reply packets traverse the Linux bridge at L2 and skip the
reverse-NAT in conntrack. The client sees replies from the wrong source IP and
drops them.

Fix: Load br_netfilter and enable bridge-nf-call-iptables.

Problem 3: Ollama listens on 127.0.0.1 only

If using local Ollama for inference, it defaults to 127.0.0.1:11434 which is
unreachable from inside the OpenShell sandbox container. The onboarding fails at
step [5/7] with:

containers cannot reach http://host.openshell.internal:11434

Fix: Configure Ollama to listen on 0.0.0.0:11434.

Prerequisites

Step 0a: Install curl

sudo apt install curl

Step 0b: Install Docker

Remove any old Docker packages:

sudo apt-get remove docker docker-engine docker.io containerd runc

Add Docker’s official GPG key and repository:

sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Step 0c: Install NVIDIA Container Toolkit

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
  | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
  | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

Configure the toolkit for all runtimes:

sudo nvidia-ctk runtime configure --runtime=docker
sudo nvidia-ctk runtime configure --runtime=containerd
sudo nvidia-ctk runtime configure --runtime=crio
sudo systemctl restart docker
sudo systemctl restart containerd
sudo systemctl restart crio

Step 0d: Add user to the docker group

sudo chmod 666 /var/run/docker.sock
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

Step 0e: Set NVIDIA as default Docker runtime

This is needed so that the NVCC compiler and GPU are available during
docker build operations. Edit /etc/docker/daemon.json:

sudo nano /etc/docker/daemon.json

Set the contents to:

{
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    },
    "default-runtime": "nvidia"
}

Then reconfigure and restart:

sudo nvidia-ctk runtime configure --runtime=docker
sudo nvidia-ctk runtime configure --runtime=containerd
sudo nvidia-ctk runtime configure --runtime=crio
sudo systemctl restart docker
sudo systemctl restart containerd
sudo systemctl restart crio
sudo systemctl enable docker.service
sudo systemctl enable containerd.service

NemoClaw Setup Steps

Run these steps in order before launching the NemoClaw installer.

Step 1: Load br_netfilter kernel module

sudo modprobe br_netfilter
sudo sysctl -w net.bridge.bridge-nf-call-iptables=1

Make it persistent across reboots:

echo br_netfilter | sudo tee /etc/modules-load.d/k8s.conf
echo 'net.bridge.bridge-nf-call-iptables = 1' | sudo tee /etc/sysctl.d/k8s.conf

Step 2: Patch the OpenShell cluster image to use iptables-legacy

The installer pulls ghcr.io/nvidia/openshell/cluster:0.0.13 and uses it
directly. We patch it in-place so the installer picks up the fixed version.

IMAGE_NAME="ghcr.io/nvidia/openshell/cluster:0.0.13"

docker run --entrypoint sh --name fix-iptables "$IMAGE_NAME" -c '
  update-alternatives --set iptables /usr/sbin/iptables-legacy
  update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
  ln -sf /usr/sbin/iptables-legacy /usr/sbin/iptables
  ln -sf /usr/sbin/ip6tables-legacy /usr/sbin/ip6tables
  iptables --version
'

docker commit \
  --change 'ENTRYPOINT ["/usr/local/bin/cluster-entrypoint.sh"]' \
  fix-iptables "$IMAGE_NAME"

docker rm fix-iptables

You should see iptables v1.8.10 (legacy) in the output.

Important: If the installer re-pulls the image (e.g., on a retry after
cleanup), this patch is lost. Re-run this step before each installer attempt.

Step 3: Configure Ollama to listen on all interfaces

Skip this step if using NVIDIA cloud inference (build.nvidia.com) instead of local Ollama.

sudo mkdir -p /etc/systemd/system/ollama.service.d
echo -e '[Service]\nEnvironment="OLLAMA_HOST=0.0.0.0:11434"' \
  | sudo tee /etc/systemd/system/ollama.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart ollama

Verify:

ss -tlnp | grep 11434
# Should show 0.0.0.0:11434, NOT 127.0.0.1:11434

Step 4: Run the NemoClaw installer

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

During onboarding, you will be prompted for:

  • Sandbox name: accept the default my-assistant or choose your own
  • Inference option: choose 2 for local Ollama
  • Ollama model: choose from available models (e.g., qwen3.5:2b)

The Docker image build at step [3/7] takes ~10 minutes on Orin (first run, no
cache). Subsequent runs are faster due to layer caching.

Verification

After successful onboarding, the dashboard should be accessible at:

http://127.0.0.1:18789/

The OpenShell gateway runs at:

https://127.0.0.1:8080

Troubleshooting

Check if the sandbox pod is healthy

docker exec openshell-cluster-nemoclaw kubectl get pods -n openshell

Check sandbox pod logs

docker exec openshell-cluster-nemoclaw kubectl logs -n openshell my-assistant

Test DNS inside the cluster

docker exec openshell-cluster-nemoclaw kubectl run dns-test \
  --namespace=openshell \
  --image=rancher/mirrored-library-busybox:1.37.0 \
  --restart=Never \
  -- nslookup openshell.openshell.svc.cluster.local

sleep 10

docker exec openshell-cluster-nemoclaw kubectl logs -n openshell dns-test
docker exec openshell-cluster-nemoclaw kubectl delete pod -n openshell dns-test

Check iptables version inside the cluster

docker exec openshell-cluster-nemoclaw iptables --version
# Must say "(legacy)", NOT "(nf_tables)"

Check br_netfilter is active

lsmod | grep br_netfilter
cat /proc/sys/net/bridge/bridge-nf-call-iptables
# Must output: 1

Clean up and start fresh

# Stop and remove everything
source ~/.bashrc
nemoclaw destroy 2>/dev/null
docker rm -f openshell-cluster-nemoclaw 2>/dev/null
docker volume prune -f

# Then re-run from Step 2 above

3 Likes