In den letzten zwei Beiträgen habe ich Euch gezeigt, wie ich NemoClaw auf einem Dell OptiPlex 5040 mit Ubuntu 24.04 aufgesetzt habe und wie ich aus dem Sandbox-Start einen systemd-Service gemacht habe, der beim Boot automatisch hochfährt. Damit habe ich einen gut wartbaren lokalen Agenten-Host aufgesetzt. Aber bisher kann der OpenClaw-Agent in der Sandbox nur mit dem lokalen Ollama-Server reden. Was noch fehlt: Internetzugriff zum Surfen und Scrapen.
Genau das löse ich in diesem Beitrag. Ich zeige Euch, wie ich auf meinem zweiten Server (einer RTX A6000 Ada Workstation, IP 192.168.2.119) Firecrawl self-hosted installiert habe und wie ich anschließend die OpenShell-Egress-Policy in NemoClaw so konfiguriert habe, dass der OpenClaw-Agent aus der Sandbox heraus Firecrawl ansprechen darf. Ergebnis: Ein vollständig souveräner Stack, in dem mein Agent Webseiten scrapen und durchsuchen kann.
Die Zielarchitektur
Bevor ich loslege, kurz das Gesamtbild:
- NemoClaw-Host (192.168.178.142): Mein OptiPlex 5040 mit der OpenClaw-Sandbox.
- Ollama-Server (192.168.2.57): Mein A6000-Inferenz-Server mit qwen3.5:35b und weiteren Modellen.
- Firecrawl-Host (192.168.2.119): Meine A6000Ada-Workstation mit dem Firecrawl-Stack auf Port 3002.
Die Aufgabe: Den OpenClaw-Agenten innerhalb der NemoClaw-Sandbox so anbinden, dass er HTTP-Requests an die Firecrawl-API senden kann und wirklich nur dorthin. Alles andere bleibt durch OpenShells „deny by default„-Modell weiter geblockt. Das ist der Kern des Sovereign-AI-Ansatzes: Feingranulare Allow-Listen statt offener Tore. Aber so einfach war es nicht denn ich musste erst noch die NVIDIA OpenShell verstehen lernen.
1. Firecrawl self-hosted installieren
Auf dem Firecrawl-Host (192.168.2.119) habe ich das offizielle Repository nach /opt/firecrawl geklont:
Befehl: cd /opt && sudo git clone https://github.com/firecrawl/firecrawl.git
Die aktuelle Firecrawl-Version nutzt eine etwas erweiterte Architektur gegenüber der populären „Self-Hosting-Anleitung“, die in der Community kursiert: Zusätzlich zu api, playwright-service und redis kommen jetzt nuq-postgres (für Queue-Persistenz) und rabbitmq (als Message-Broker) hinzu. Das bedeutet auch: Die Konfiguration verlangt ein paar zusätzliche Variablen in der .env. Daher ist es ganz wichtig, dass ihr die online Dokumentation für die lokale Installation (https://github.com/firecrawl/firecrawl/blob/main/SELF_HOST.md) von FireCrawl euch genau anschaut.
Hier meine funktionierende .env mit den wichtigsten Punkten:
PORT=3002
HOST=0.0.0.0
USE_DB_AUTHENTICATION=false
# OpenAI-kompatibler Endpoint von Ollama (nicht /api, sondern /v1!)
OPENAI_BASE_URL=http://192.168.2.57:11434/v1
OPENAI_API_KEY=ollama
MODEL_NAME=qwen3.5:35b
MODEL_EMBEDDING_NAME=qwen3-embedding:4b
BULL_AUTH_KEY=<langer-zufaelliger-string>
ALLOW_LOCAL_WEBHOOKS=true
Wichtig: Die Variable heißt jetzt OPENAI_BASE_URL, nicht mehr OLLAMA_BASE_URL. Und der Pfad ist /v1 für den OpenAI-kompatiblen Endpoint, nicht /api. Das hat mich ehrlich gesagt einige Zeit Debugging gekostet bis ich den Fehler gefunden hatte.
2. Race-Condition beim Container-Start umschiffen
Beim ersten docker compose up -d bin ich in eine klassische Race-Condition gelaufen: Der firecrawl-api-Container startete schneller als der nuq-postgres-Container „accepting connections“ melden konnte. Ergebnis: Der API-Container crashte mit ECONNREFUSED 172.19.0.2:5432 und nahm gleich alle Worker-Prozesse mit in den Tod.
Mein Workaround: Postgres erst alleine hochfahren, kurz warten, dann den Rest:
cd /opt/firecrawl
sudo docker compose up -d nuq-postgres rabbitmq redis playwright-service
sleep 20
sudo docker compose up -d api
Nach dieser Sequenz waren alle Container Up, und Firecrawl antwortete vom Host aus auf http://192.168.2.119:3002/ mit dem erwarteten JSON:
{"message":"Firecrawl API","documentation_url":"https://docs.firecrawl.dev"}
Diese Anleitung enthält das wichtige Detail, das ich später noch ausführlich in einem separaten Beitrag erklären werde: Wer sich an die populäre alte Anleitung hält, läuft in der aktuellen Firecrawl-Version unweigerlich in diese Race-Condition. Notiert Euch das schon mal.
3. OpenShell-Policy verstehen: Das zweistufige Modell
Jetzt zum eigentlich spannenden Teil. NemoClaw nutzt OpenShell (https://github.com/NVIDIA/OpenShell) als Sandbox-Runtime, und OpenShell setzt eine strikte deny-by-default-Netzwerkpolicy durch. Der OpenClaw-Agent in der Sandbox kann von sich aus nur das Inference-Backend (Ollama via inference.local) erreichen. Das ist so gewollt und auch richtig und so ist alles andere geblockt. Genau dafür lassen wir ja OpenClaw als NeMo Clar in der OpenShell Sandbox von NVIDIA laufen.a
Schauen wir uns die aktuelle Policy an. Auf dem NemoClaw-Host:
Befehl: openshell policy get openclawbox --full
Das gibt die vollständige Policy als YAML aus. Im Block network_policies sehe ich Einträge wie diesen für die NVIDIA-API:
nvidia:
endpoints:
- host: integrate.api.nvidia.com
port: 443
protocol: rest
enforcement: enforce
rules:
- allow:
method: POST
path: /v1/chat/completions
- allow:
method: GET
path: /v1/models
binaries:
- path: /usr/local/bin/openclaw
Hier sieht man bereits das zweistufige Modell, das OpenShell durchsetzt:
- Endpoint-Regeln: Welche HTTP-Methoden und Pfade sind für diesen Host:Port erlaubt?
- Binaries-Liste: Welche Programme in der Sandbox dürfen diesen Endpoint überhaupt nutzen?
Beide Filter müssen erfüllt sein. Eine Endpoint-Regel ohne passende Binaries-Liste bedeutet: Niemand darf den Endpoint nutzen und die Regel wäre dann effektiv tot. Genau das war mir passiert da ich die Binaries-Liste und deren Aufgabe nicht gleich verstanden hatte.
4. Firecrawl-Endpoint zur Policy hinzufügen
Mein erster Versuch ging über die --add-endpoint und --add-allow Subcommands von openshell policy update. Das funktioniert, hat aber bei mir zu einer aufgeblähten Policy mit teilweise redundanten Regeln geführt (weil --add-endpoint mit dem read-write-Preset automatisch eine Reihe von Methoden-Regeln expandiert). Außerdem habe ich dabei die Binaries-Liste vergessen. Das war mein größter Fehler im Debugging-Verlauf.
Hier findet ihr aber eine sehr gute Erklärung direkt von NVIDIA: https://docs.nvidia.com/nemoclaw/latest/reference/network-policies
Der sauberere Weg: Eine vollständige Policy-Datei generieren und mit openshell policy set komplett ersetzen. Hier mein Python-Skript, das die aktuelle Policy holt, den Firecrawl-Block sauber einfügt und das Ganze zurückschreibt:
# Aktuelle Policy holen und Metadaten-Header entfernen
openshell policy get openclawbox --full > /tmp/policy.yaml
sed -i '1,/^---$/d' /tmp/policy.yaml
# Python ersetzt den Block sauber (preserviert Einrückung)
python3 << 'EOF'
import yaml
with open('/tmp/policy.yaml', 'r') as f:
policy = yaml.safe_load(f)
policy['network_policies']['allow_192_168_2_119_3002'] = {
'name': 'allow_192_168_2_119_3002',
'endpoints': [{
'host': '192.168.2.119',
'port': 3002,
'protocol': 'rest',
'enforcement': 'enforce',
'rules': [
{'allow': {'method': 'GET', 'path': '/**'}},
{'allow': {'method': 'POST', 'path': '/**'}},
],
}],
'binaries': [
{'path': '/usr/bin/curl'},
{'path': '/usr/local/bin/openclaw'},
{'path': '/usr/local/bin/node'},
{'path': '/usr/bin/node'},
],
}
with open('/tmp/policy.yaml', 'w') as f:
yaml.safe_dump(policy, f, default_flow_style=False, sort_keys=False)
EOF
# Policy anwenden
openshell policy set openclawbox --policy /tmp/policy.yaml
Die wichtigen Stellen in diesem YAML-Block:
- Endpoint:
192.168.2.119:3002mit Protokollrestundenforcement: enforce. - Rules: GET und POST auf
/**– damit darf der Agent sowohl Status abfragen als auch Scrape-Jobs starten. - Binaries:
/usr/bin/curl,/usr/local/bin/openclawund die Node-Binaries. Ohne diesen Block wäre die Regel komplett unwirksam und zwar egal wie schön die Endpoint-Definition aussieht.
5. Policy aktivieren und verifizieren
Nach dem policy set ist die neue Policy zunächst im Zustand Pending. Das Gateway braucht ein paar Sekunden, um sie scharf zu schalten.
Befehl: openshell policy get openclawbox
Erwartet wird:
Version: 10
Status: Loaded
Active: 10
Sobald Active und Status: Loaded stimmen, ist die Policy wirksam. Jetzt der Realitätstest aus der Sandbox heraus:
Befehl: nemoclaw openclawbox connect
Wenn ihr in der Sandbox drinnen seid gebt ihr bitte folgenden Befehl ein.:
Befehl: curl http://192.168.2.119:3002/
Erwartete Ausgabe:
{"message":"Firecrawl API","documentation_url":"https://docs.firecrawl.dev"}
Und der eigentliche Scrape-Test:
Befehl: curl -X POST http://192.168.2.119:3002/v2/scrape -H 'Content-Type: application/json' -d '{"url":"https://ai-box.eu","formats":["markdown"]}'
Wenn das eine echte Firecrawl-Antwort mit gescrapetem Markdown zurückgibt, ist die volle Pipeline durchgängig: Sandbox → OpenShell-Proxy → Policy-Check → LAN-Routing → Firecrawl.
Mein persönliches Fazit
Was ich heute aufgebaut habe, ist mehr als nur ein Web-Scraping-Setup. Es ist der erste Baustein eines Sovereign-AI-Stacks, in dem jeder einzelne Layer unter meiner Kontrolle steht: Der Agent läuft lokal in einer Sandbox, die Inferenz läuft lokal auf meinem Ollama-Server, und das Web-Scraping läuft lokal auf einer eigenen Workstation. Kein einziger Cloud-Dienst ist involviert.
Was ich als Maker besonders schätze: Die Hürde dafür ist gar nicht so hoch, wenn man die richtigen Werkzeuge kennt. Firecrawl ist Open Source, OpenShell ist Open Source, NemoClaw und OpenClaw sind Open Source. Was es braucht, ist Geduld beim Debugging und das Verständnis für das zweistufige Policy-Modell mit Endpoint-Rules und Binaries-Liste.
Genau letzteres ist der Punkt, an dem ich beim Schreiben dieses Beitrags am längsten hängengeblieben bin: Ohne die Binaries-Sektion in der Policy bleibt jede Endpoint-Regel wirkungslos. In der NemoClaw-Doku steht das zwischen den Zeilen, aber es ist die eine Erkenntnis, die in jedem Tutorial zu OpenShell prominent ganz oben stehen muss. Vielleicht hilft dieser Beitrag ja dem nächsten Maker, der sich in das System einarbeitet.
Im nächsten Beitrag zeige ich Euch, wie ich Firecrawl an Ollama angebunden habe und dem OpenClaw-Agent die ersten echten Recherche-Aufgaben gegeben habe.
Wir lesen uns im nächsten Teil!






Ein toller Guide der leicht zugänglich und verständlich ist. Perfekt für ein kleines Side-Project geeignet. Aktuell half mir noch mein…
Thank you for this great tutorial, could you share n8n workflow and comfyui workflow please?
Hallo Anton, die Meldung besagt das in meinem Beisiel Methoden verwendet werden die veraltet (deprecated) sind. Also müsstest Du die…
Danke für das Tool! Ich habe erst kürzlich angefangen mich mit der Thematik zu beschäftigen und bin für meine Erwartungen…
Hallo, ich habe ihre Anleitung befolgt und bekomme im letzten Schritt leider immer folgende Meldung im Terminal: bash <(wget -qO-…