DGX Spark · NemoClaw · OpenClaw · OpenShell

Install NemoClaw / OpenClaw on DGX Spark Behind a Proxy

A practical step-by-step installation guide for DGX Spark users running Docker, OpenShell, NemoClaw, OpenClaw, local Ollama models, GPU passthrough, and a proxy such as Clash Verge.

Docker proxy Container proxy Airgap gateway image Local Docker registry GPU passthrough Local Ollama
This sanitized version removes personal usernames, machine-specific usernames, and private LAN addresses. Replace all placeholders such as <DGX_IP>, <SSH_USER>, and <MODEL_NAME> with your own values.

0. Replace placeholders

Use your own values before running commands.

export DGX_IP="<DGX_IP>"
export PROXY_PORT="<PROXY_PORT>"
export PROXY="http://${DGX_IP}:${PROXY_PORT}"
export SSH_USER="<SSH_USER>"
export OPENCLAW_GATEWAY_IMAGE="ghcr.io/nvidia/openshell/cluster:0.0.36"
export AIRGAP_IMAGE="localhost:5000/openshell-cluster-airgap:0.0.36"
export OLLAMA_MODEL="<MODEL_NAME>"

Example model names may include locally available Ollama models such as nemotron-3-super:120b, but use the model actually installed on your machine.

1. Check basic system status

hostname -I
node -v
npm -v
docker --version
nvidia-smi

Check Docker can see the NVIDIA GPU:

docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

If Docker cannot pull ubuntu, fix Docker proxy first.

2. Configure shell proxy and Git proxy

If your proxy runs on the DGX Spark host, make sure the proxy allows LAN access and use the host IP instead of 127.0.0.1 when containers need to reach it.

export http_proxy="${PROXY}"
export https_proxy="${PROXY}"
export HTTP_PROXY="${PROXY}"
export HTTPS_PROXY="${PROXY}"
export no_proxy="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10"
export NO_PROXY="$no_proxy"

Configure Git:

git config --global http.proxy "${PROXY}"
git config --global https.proxy "${PROXY}"
git config --global http.version HTTP/1.1

Test connectivity:

curl -x "${PROXY}" -I https://github.com --max-time 20
curl -x "${PROXY}" -I https://ghcr.io/v2/ --max-time 20
curl -x "${PROXY}" -I https://registry-1.docker.io/v2/ --max-time 20
git ls-remote https://github.com/NVIDIA/NemoClaw.git | head

For Docker Hub, HTTP/2 401 is normal. It means the registry is reachable but unauthenticated.

3. Configure Docker daemon proxy

Docker daemon does not automatically inherit shell proxy variables.

sudo mkdir -p /etc/systemd/system/docker.service.d

sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf > /dev/null <<EOF
[Service]
Environment="HTTP_PROXY=${PROXY}"
Environment="HTTPS_PROXY=${PROXY}"
Environment="NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10"
Environment="http_proxy=${PROXY}"
Environment="https_proxy=${PROXY}"
Environment="no_proxy=localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10"
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

Verify without entering a pager:

systemctl --no-pager show --property=Environment docker
docker info | grep -i -E "proxy|http|https" || true

Test image pulls:

for i in 1 2 3; do
  echo "=== test $i ==="
  docker pull ghcr.io/nvidia/openshell/cluster:0.0.36
  docker pull docker.io/rancher/mirrored-pause:3.6
done

4. Configure Docker container proxy

This makes newly created containers receive proxy environment variables.

mkdir -p ~/.docker

cat > ~/.docker/config.json <<EOF
{
  "proxies": {
    "default": {
      "httpProxy": "${PROXY}",
      "httpsProxy": "${PROXY}",
      "noProxy": "localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10"
    }
  }
}
EOF

Test:

docker run --rm --entrypoint env ghcr.io/nvidia/openshell/cluster:0.0.36 | grep -i proxy

Expected output should include HTTP_PROXY and HTTPS_PROXY.

5. Install NemoClaw CLI

curl -fsSL --retry 5 --retry-all-errors -L \
  https://www.nvidia.com/nemoclaw.sh \
  -o /tmp/nemoclaw_install.sh

ls -lh /tmp/nemoclaw_install.sh
head -n 20 /tmp/nemoclaw_install.sh

bash /tmp/nemoclaw_install.sh

Check installation:

source ~/.bashrc
which nemoclaw
nemoclaw --version
openshell --version

If GitHub cloning fails with TLS errors, repeat the proxy tests and confirm:

git ls-remote https://github.com/NVIDIA/NemoClaw.git | head

A Python externally-managed-environment warning may appear during model-router installation. In the tested workflow, it did not block the core NemoClaw CLI installation.

6. Why a custom airgap gateway image is needed

The OpenShell gateway is a Docker container that starts an embedded k3s cluster. Even when Docker daemon proxy is correct, the k3s/containerd inside the gateway may fail to pull required images.

Common failing images include:

rancher/mirrored-pause:3.6
rancher/mirrored-metrics-server:v0.8.1
rancher/local-path-provisioner:v0.0.35
rancher/klipper-helm:v0.9.14-build20260309
rancher/mirrored-coredns-coredns:1.14.2
registry.k8s.io/agent-sandbox/agent-sandbox-controller:v0.1.0

Typical errors include:

ImagePullBackOff
ErrImagePull
failed to pull
TLS handshake timeout
connection reset by peer
EOF

The robust fix is to preload these images into /var/lib/rancher/k3s/agent/images/ inside a custom OpenShell cluster image.

7. Pull all required k3s images

IMAGES=(
  docker.io/rancher/mirrored-pause:3.6
  docker.io/rancher/mirrored-metrics-server:v0.8.1
  docker.io/rancher/local-path-provisioner:v0.0.35
  docker.io/rancher/klipper-helm:v0.9.14-build20260309
  docker.io/rancher/mirrored-coredns-coredns:1.14.2
  registry.k8s.io/agent-sandbox/agent-sandbox-controller:v0.1.0
)

for img in "${IMAGES[@]}"; do
  echo "=== pulling $img ==="
  for i in 1 2 3 4 5; do
    docker pull "$img" && break
    echo "retry $i failed: $img"
    sleep 5
  done
done

Save them into one airgap tarball:

docker save \
  docker.io/rancher/mirrored-pause:3.6 \
  docker.io/rancher/mirrored-metrics-server:v0.8.1 \
  docker.io/rancher/local-path-provisioner:v0.0.35 \
  docker.io/rancher/klipper-helm:v0.9.14-build20260309 \
  docker.io/rancher/mirrored-coredns-coredns:1.14.2 \
  registry.k8s.io/agent-sandbox/agent-sandbox-controller:v0.1.0 \
  -o /tmp/openshell-k3s-images-airgap.tar

ls -lh /tmp/openshell-k3s-images-airgap.tar

8. Build the custom OpenShell airgap image

mkdir -p /tmp/openshell-cluster-airgap
cp /tmp/openshell-k3s-images-airgap.tar /tmp/openshell-cluster-airgap/

cat > /tmp/openshell-cluster-airgap/Dockerfile <<EOF
FROM ghcr.io/nvidia/openshell/cluster:0.0.36

USER root

RUN mkdir -p /var/lib/rancher/k3s/agent/images

COPY openshell-k3s-images-airgap.tar \
  /var/lib/rancher/k3s/agent/images/openshell-k3s-images-airgap.tar

ENV HTTP_PROXY=${PROXY}
ENV HTTPS_PROXY=${PROXY}
ENV http_proxy=${PROXY}
ENV https_proxy=${PROXY}
ENV NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10
ENV no_proxy=localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10
EOF

docker build \
  -t local/openshell-cluster-airgap:0.0.36 \
  -t localhost:5000/openshell-cluster-airgap:0.0.36 \
  /tmp/openshell-cluster-airgap

Test the image:

docker run --rm --entrypoint sh local/openshell-cluster-airgap:0.0.36 -lc '
  env | grep -i proxy
  ls -lh /var/lib/rancher/k3s/agent/images/
'

9. Start a local Docker registry

OpenShell may try to docker pull the image. A pure local tag may be treated as a remote repository. Use a local registry instead.

docker rm -f local-registry 2>/dev/null || true

docker run -d \
  --name local-registry \
  --restart unless-stopped \
  -p 5000:5000 \
  registry:2

Check:

docker ps | grep local-registry

Push the airgap image:

docker push localhost:5000/openshell-cluster-airgap:0.0.36
docker pull localhost:5000/openshell-cluster-airgap:0.0.36

10. Start OpenShell gateway with GPU

Clean old state:

openshell gateway destroy --name nemoclaw || true
openshell gateway destroy -g nemoclaw || true

docker rm -f openshell-cluster-nemoclaw 2>/dev/null || true
docker volume ls -q --filter "name=openshell-cluster-nemoclaw" | xargs -r docker volume rm

Start gateway using the local registry image:

OPENSHELL_CLUSTER_IMAGE=localhost:5000/openshell-cluster-airgap:0.0.36 \
openshell gateway start --name nemoclaw --gpu

Expected success:

✓ Checking Docker
✓ Downloading gateway
✓ Initializing environment
✓ Starting gateway
✓ Gateway ready

Name: nemoclaw
Endpoint: https://127.0.0.1:8080

✓ Active gateway set to 'nemoclaw'

Verify image and health:

docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" | grep openshell

docker inspect --format '{{.State.Health.Status}}' openshell-cluster-nemoclaw

Verify GPU passthrough:

docker inspect openshell-cluster-nemoclaw \
  --format 'Image={{.Config.Image}} DeviceRequests={{json .HostConfig.DeviceRequests}}'

Inside logs, a good sign is:

Got registration request from device plugin with resourceName="nvidia.com/gpu"

11. Run NemoClaw onboarding

nemoclaw onboard --gpu

Recommended choices

Brave Web Search

Choose N at first. Enable it later after the core system works.

Messaging channels

Skip Telegram, Discord, and Slack initially. Add them later when you have tokens ready.

Policy presets

Use Balanced, keep npm, pypi, huggingface, brew, brave, and local-inference.

GitHub

Enable github if you want the sandbox to work with source repositories.

12. Access the OpenClaw UI

At the end of onboarding, NemoClaw should show something like:

OpenClaw UI
Dashboard: http://127.0.0.1:18789/
Token: nemoclaw my-assistant gateway-token --quiet

Get token:

nemoclaw my-assistant gateway-token --quiet

If your browser is on the DGX Spark machine, open:

http://127.0.0.1:18789/

If you are connecting from another computer, use SSH port forwarding from your local computer:

ssh -L 18789:127.0.0.1:18789 <SSH_USER>@<DGX_IP>

Then open locally:

http://127.0.0.1:18789/

If the browser asks for auth, append:

http://127.0.0.1:18789/#token=<your-token>

Do not publish your token.

13. Useful status commands

nemoclaw list
openshell gateway status

docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

docker logs --tail=300 openshell-cluster-nemoclaw | \
  grep -Ei "ImagePull|ErrImage|BackOff|failed to pull|EOF|error|failed|nvidia|gpu|openshell"

14. Troubleshooting

Problem: curl: SSL_ERROR_SYSCALL

curl -x "${PROXY}" -I https://registry-1.docker.io/v2/ --max-time 20

If Docker Hub returns 401, it is reachable.

Problem: git clone fails with gnutls_handshake()

git config --global http.proxy "${PROXY}"
git config --global https.proxy "${PROXY}"
git config --global http.version HTTP/1.1

Problem: Docker pull fails but curl works

Docker daemon needs its own proxy. Repeat Step 3.

Problem: New containers do not have proxy variables

docker run --rm --entrypoint env ghcr.io/nvidia/openshell/cluster:0.0.36 | grep -i proxy

Problem: OpenShell gateway uses default GHCR image instead of airgap image

docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" | grep openshell

The image should be:

localhost:5000/openshell-cluster-airgap:0.0.36

Problem: pull access denied for local/openshell-cluster-airgap

Do not use a pure local image tag as OPENSHELL_CLUSTER_IMAGE. Use the local registry image:

localhost:5000/openshell-cluster-airgap:0.0.36

Problem: ImagePullBackOff inside gateway

Find the missing image:

docker logs --tail=300 openshell-cluster-nemoclaw | \
  grep -Ei "ImagePull|ErrImage|BackOff|failed to pull|EOF|manifest"

Pull it on the host, add it to the docker save command in Step 7, rebuild the airgap image, push it to the local registry, and restart gateway.

Problem: Existing gateway was started without GPU passthrough

openshell gateway destroy --name nemoclaw || true

docker rm -f openshell-cluster-nemoclaw 2>/dev/null || true

docker volume ls -q --filter "name=openshell-cluster-nemoclaw" | xargs -r docker volume rm

OPENSHELL_CLUSTER_IMAGE=localhost:5000/openshell-cluster-airgap:0.0.36 \
openshell gateway start --name nemoclaw --gpu

nemoclaw onboard --gpu

Problem: Ollama reachability warning during onboarding

You may see a warning that local Ollama is responding on 127.0.0.1 but Docker container reachability failed. If NemoClaw still creates the provider and sets the inference route, continue and test inference after onboarding.

15. Final expected result

NemoClaw CLI installed
OpenShell gateway ready
GPU passthrough enabled
Ollama local inference provider configured
OpenClaw launched inside sandbox
OpenClaw UI available at http://127.0.0.1:18789/

Core commands for daily use:

openshell gateway status
nemoclaw list
nemoclaw my-assistant gateway-token --quiet