This commit is contained in:
Leopere 2026-02-24 16:14:53 -05:00
parent eb3f3d4134
commit 99e7df77ba
Signed by: colin
SSH Key Fingerprint: SHA256:nRPCQTeMFLdGytxRQmPVK9VXY3/ePKQ5lGRyJhT5DY8
7 changed files with 295 additions and 19 deletions

View File

@ -2,6 +2,14 @@
Welcome to Clawtainer! This desktop has OpenClaw Gateway pre-installed and running on port 18789. Welcome to Clawtainer! This desktop has OpenClaw Gateway pre-installed and running on port 18789.
## Container layout
- **Desktop (VNC):** http://localhost:6901 (via nginx proxy)
- **OpenClaw Gateway:** http://localhost:18789
- **Gateway token:** `clawtainer` (enter in Settings → token)
- **Config:** `~/.openclaw/openclaw.json` (inside the container; `/home/kasm-user/.openclaw/`)
- **Env vars:** Project `.env` is loaded by Docker Compose; `GROQ_API_KEY`, `TELEGRAM_BOT_TOKEN`, etc. are passed into the container.
## What is OpenClaw? ## What is OpenClaw?
OpenClaw is an open-source AI agent orchestration platform that connects to AI provider APIs. The Gateway is already running in the background, but you need to configure it with your API keys. OpenClaw is an open-source AI agent orchestration platform that connects to AI provider APIs. The Gateway is already running in the background, but you need to configure it with your API keys.
@ -30,32 +38,20 @@ This will guide you through:
### Option 3: Manual Configuration ### Option 3: Manual Configuration
Create or edit `~/.openclaw/openclaw.json`: Create or edit `~/.openclaw/openclaw.json` inside the desktop (or merge config and `docker cp` it in). For **built-in providers** (Anthropic, OpenAI, Google, Groq), you can also use environment variables: add keys to the project `.env` and ensure they're in `docker-compose.yml` `environment` so they reach the container.
Example manual `models.providers`:
```json ```json
{ {
"models": { "models": {
"providers": { "providers": {
"anthropic": { "anthropic": { "apiKey": "sk-ant-your-key-here" },
"apiKey": "sk-ant-your-key-here" "openai": { "apiKey": "sk-your-key-here" },
}, "google": { "apiKey": "AIza-your-key-here" }
"openai": {
"apiKey": "sk-your-key-here"
},
"google": {
"apiKey": "AIza-your-key-here"
} }
} }
} }
}
```
Or use environment variables in `~/.bashrc`:
```bash
export ANTHROPIC_API_KEY="sk-ant-your-key-here"
export OPENAI_API_KEY="sk-your-key-here"
export GOOGLE_API_KEY="AIza-your-key-here"
``` ```
## Get API Keys ## Get API Keys
@ -78,6 +74,61 @@ You'll need API keys from at least one provider:
- Best for: Access to multiple models through one API - Best for: Access to multiple models through one API
- Pricing: Varies by model selected - Pricing: Varies by model selected
- **Groq**: https://console.groq.com/keys
- Best for: Very fast inference (Llama 3.x, GPT-OSS). OpenAI-compatible API.
- Pricing: Low cost per token, free tier available.
### Using Groq with Clawtainer
Put `GROQ_API_KEY` in the project `.env`. Docker Compose passes it into the container.
**Option A: Script (recommended)**
From the project root, after `docker compose up -d`:
```bash
./scripts/configure-groq.sh
docker exec clawtainer openclaw gateway restart
```
> **Note:** The script **overwrites** `~/.openclaw/openclaw.json` with a Groq-only config. If you have other providers or channels, run the script first, then add them manually to `openclaw.json`.
**Option B: Manual config**
Inside the desktop, edit `~/.openclaw/openclaw.json`. Add under `models.providers` (merge with existing providers if present):
```json
"groq": {
"baseUrl": "https://api.groq.com/openai/v1",
"api": "openai-completions",
"apiKey": "your-groq-api-key",
"models": [
{ "id": "llama-3.3-70b-versatile", "name": "Llama 3.3 70B", "contextWindow": 131072 },
{ "id": "llama-3.1-8b-instant", "name": "Llama 3.1 8B", "contextWindow": 131072 }
]
}
```
Use `"api": "openai-completions"` (not `"openai"`). Wrong API type can cause **Verification failed: status 404**.
**Groq model IDs**
| Model ID | Notes |
|----------|-------|
| `groq/llama-3.3-70b-versatile` | Best quality, 280 tok/s |
| `groq/llama-3.1-8b-instant` | Faster, cheaper |
| `groq/openai/gpt-oss-120b` | OpenAI OSS 120B |
Set default: add `"agents": { "defaults": { "model": { "primary": "groq/llama-3.3-70b-versatile" } } }` to `openclaw.json`.
**Verify your Groq key**
```bash
curl -s "https://api.groq.com/openai/v1/models" -H "Authorization: Bearer $GROQ_API_KEY" | head -20
```
If you get JSON back, the key works. If 401, the key is invalid. If 404, the URL is wrong.
## Verify Setup ## Verify Setup
After adding keys, test the connection: After adding keys, test the connection:
@ -88,6 +139,107 @@ openclaw gateway status
Or visit `http://localhost:18789` to see the Gateway control panel. Or visit `http://localhost:18789` to see the Gateway control panel.
## Messaging Channels (WhatsApp, Telegram, Discord, Signal, …)
You can add WhatsApp, Telegram, Discord, **Signal**, and other channels so the agent is reachable from your phone or team chat. Config lives in `~/.openclaw/openclaw.json` under `channels`. Restart the gateway after changes: `openclaw gateway restart`.
**Install all channel plugins (no container rebuild):** Run `./scripts/install-channel-clients.sh` to add Mattermost, Teams, Matrix, Nostr, Zalo, and signal-cli into the running container via `docker exec`. Then restart: `docker exec clawtainer openclaw gateway restart`.
### Telegram
1. In Telegram, open a chat with **@BotFather**, run `/newbot`, and copy the bot token.
2. Add the token to `.env` as `TELEGRAM_BOT_TOKEN=...` (Clawtainer passes it into the container), or put it in `openclaw.json` under `channels.telegram.botToken`.
3. Add a `channels.telegram` block in `~/.openclaw/openclaw.json` (merge with existing `channels` if present):
```json
"channels": {
"telegram": {
"enabled": true,
"dmPolicy": "pairing",
"groups": { "*": { "requireMention": true } }
}
}
```
4. Restart the gateway, then approve DMs: `openclaw pairing list telegram` and `openclaw pairing approve telegram <CODE>`.
- Docs: https://docs.openclaw.ai/channels/telegram
### Discord
1. In the [Discord Developer Portal](https://discord.com/developers/applications), create an application, add a Bot, and copy the bot token.
2. Add to `.env` as `DISCORD_BOT_TOKEN=...` (Clawtainer passes it in), or set `channels.discord.token` in `openclaw.json`.
3. Add a `channels.discord` block:
```json
"channels": {
"discord": {
"enabled": true,
"dmPolicy": "pairing",
"allowFrom": ["YOUR_DISCORD_USER_ID"]
}
}
```
4. Invite the bot to your server (OAuth2 → URL Generator, scopes: bot; permissions as needed). Restart the gateway.
- Docs: https://docs.openclaw.ai/gateway/configuration-reference (Discord section)
### WhatsApp
WhatsApp uses the gateways web channel (Baileys). A linked session must exist before WhatsApp will start.
1. In `~/.openclaw/openclaw.json`, ensure the web channel and WhatsApp are enabled:
```json
"channels": {
"whatsapp": {
"dmPolicy": "pairing",
"allowFrom": ["+15555550123"],
"groups": { "*": { "requireMention": true } }
}
},
"web": { "enabled": true }
```
2. **Link a session once** (from a terminal inside the Clawtainer desktop, or via the Control UI if it supports pairing):
- Run `openclaw channels login` and complete the QR/linking flow for WhatsApp.
3. Restart the gateway. WhatsApp will start when the linked session exists.
- Docs: https://docs.openclaw.ai/gateway/configuration-reference (WhatsApp section)
### Signal
OpenClaw supports **Signal** (E2E encrypted) via the external CLI **signal-cli**. You get DMs, groups, reactions, read receipts, and media. Use a **dedicated bot number** (recommended) or link an existing account with QR.
**Requirements:** `signal-cli` must be installed where the gateway runs (inside the Clawtainer container if you use Docker). The native Linux build is preferred (no JVM).
1. **Path A (QR link)** Link an existing Signal account: run `signal-cli link -n "OpenClaw"` and scan the QR in Signal.
2. **Path B (dedicated number)** Register a new number: `signal-cli -a +1… register` (and `--captcha` if required; see [Signal captcha](https://signalcaptchas.org/registration/generate.html)), then `signal-cli -a +1… verify <CODE>`.
3. Add a `channels.signal` block in `~/.openclaw/openclaw.json`:
```json
"channels": {
"signal": {
"enabled": true,
"account": "+15551234567",
"cliPath": "signal-cli",
"dmPolicy": "pairing",
"allowFrom": ["+15557654321"]
}
}
```
4. Restart the gateway. Approve DMs with `openclaw pairing list signal` and `openclaw pairing approve signal <CODE>`.
**Clawtainer note:** The stock image does not include `signal-cli`. Run `./scripts/install-channel-clients.sh` to install it in the running container, or add it in a custom Dockerfile.
- Docs: https://docs.openclaw.ai/channels/signal
### Other channels
OpenClaw also supports **iMessage** (macOS only; uses `imsg` and Messages DB), **Slack** (bot + app tokens), **Google Chat** (service account), and **Mattermost** (plugin: `openclaw plugins install @openclaw/mattermost`). See the [configuration reference](https://docs.openclaw.ai/gateway/configuration-reference) for each.
## Pre-installed Tools ## Pre-installed Tools
This desktop includes: This desktop includes:
@ -108,6 +260,13 @@ You can change this by setting the `OPENCLAW_GATEWAY_TOKEN` environment variable
## Troubleshooting ## Troubleshooting
**"Health offline" in the Control UI?**
The UI connects to the gateway over WebSocket. You must **enter the gateway token** so it can authenticate:
1. Open http://localhost:18789
2. Open **Settings** (gear or settings panel)
3. Enter token: **`clawtainer`** (or whatever you set in `OPENCLAW_GATEWAY_TOKEN`)
4. Save / connect. Health should show online once the WebSocket connects with the token.
**Gateway not responding?** **Gateway not responding?**
```bash ```bash
# Check if gateway is running # Check if gateway is running
@ -122,6 +281,11 @@ openclaw gateway restart
- Verify billing is enabled on the provider's platform - Verify billing is enabled on the provider's platform
- Check for typos in the key - Check for typos in the key
**Groq: "Verification failed: status 404"?**
- Ensure `baseUrl` is exactly `https://api.groq.com/openai/v1` (no trailing slash)
- Use `"api": "openai-completions"` (not `"openai"`)
- Re-run `./scripts/configure-groq.sh` and restart the gateway, or verify your manual config matches the template
**Need help?** **Need help?**
- OpenClaw Docs: https://docs.openclaw.ai/ - OpenClaw Docs: https://docs.openclaw.ai/
- OpenClaw GitHub: https://github.com/openclaw/openclaw - OpenClaw GitHub: https://github.com/openclaw/openclaw

View File

@ -23,7 +23,9 @@ docker compose up -d
``` ```
- **Desktop**: **http://localhost:6901** (no password required) - **Desktop**: **http://localhost:6901** (no password required)
- **OpenClaw Control UI**: http://localhost:18789 (token: `clawtainer`) - **OpenClaw Control UI**: http://127.0.0.1:18789 (token: `clawtainer`)
**If localhost:18789 fails** (common on macOS): use **http://127.0.0.1:18789** instead. Run `./scripts/configure-groq.sh` to set API keys and start the gateway.
The nginx proxy strips TLS from the VNC connection for easy browser access. The nginx proxy strips TLS from the VNC connection for easy browser access.

View File

@ -8,6 +8,11 @@ services:
- "18789:18789" # OpenClaw gateway Control UI - "18789:18789" # OpenClaw gateway Control UI
environment: environment:
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-clawtainer} OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-clawtainer}
GROQ_API_KEY: ${GROQ_API_KEY:-}
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-}
DISCORD_BOT_TOKEN: ${DISCORD_BOT_TOKEN:-}
volumes:
- openclaw-data:/home/kasm-user/.openclaw
restart: unless-stopped restart: unless-stopped
networks: networks:
- clawtainer-net - clawtainer-net
@ -28,3 +33,6 @@ services:
networks: networks:
clawtainer-net: clawtainer-net:
driver: bridge driver: bridge
volumes:
openclaw-data:

29
scripts/configure-groq.sh Executable file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Writes OpenClaw Groq provider config into the running clawtainer container
# using GROQ_API_KEY from project .env. Run after: docker compose up -d
set -e
cd "$(dirname "$0")/.."
if [ ! -f .env ]; then
echo "No .env found. Add GROQ_API_KEY=your-key to .env"
exit 1
fi
# shellcheck source=/dev/null
source .env
if [ -z "${GROQ_API_KEY}" ]; then
echo "Set GROQ_API_KEY in .env"
exit 1
fi
# Escape for JSON: \ and "
key_esc="${GROQ_API_KEY//\\/\\\\}"
key_esc="${key_esc//\"/\\\"}"
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
sed "s|GROQ_API_KEY_PLACEHOLDER|$key_esc|g" scripts/openclaw-groq.json.template > "$tmp"
docker exec clawtainer mkdir -p /home/kasm-user/.openclaw/canvas /home/kasm-user/.openclaw/cron /home/kasm-user/.openclaw/workspace
docker cp "$tmp" clawtainer:"/home/kasm-user/.openclaw/openclaw.json"
docker exec -u root clawtainer chown -R 1000:1000 /home/kasm-user/.openclaw
if ! docker exec clawtainer pgrep -x openclaw >/dev/null 2>&1; then
docker exec clawtainer bash -c 'nohup openclaw gateway --bind lan --allow-unconfigured >/tmp/openclaw.log 2>&1 &'
echo "Gateway started."
fi
echo "OpenClaw configured for Groq. Control UI: http://localhost:18789 (token: clawtainer)"

View File

@ -0,0 +1,71 @@
#!/usr/bin/env bash
# Install all OpenClaw channel plugins + signal-cli into the RUNNING clawtainer
# container via docker exec. No image rebuild or container replace.
# Run after: docker compose up -d
set -e
cd "$(dirname "$0")/.."
CONTAINER="${CLAWTAINER_CONTAINER:-clawtainer}"
OPENCLAW_USER=1000
SIGNAL_CLI_VER="0.13.24"
# Channel plugins from npm (official @openclaw)
PLUGINS=(
"@openclaw/mattermost"
"@openclaw/msteams"
"@openclaw/matrix"
"@openclaw/nostr"
"@openclaw/zalo"
"@openclaw/zalouser"
)
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then
echo "Container ${CONTAINER} is not running. Start with: docker compose up -d"
exit 1
fi
echo "Installing OpenClaw channel plugins..."
for pkg in "${PLUGINS[@]}"; do
echo " -> $pkg"
docker exec -u "$OPENCLAW_USER" "$CONTAINER" \
openclaw --yes plugins install "$pkg" || true
done
echo "Installing signal-cli..."
docker exec -u root "$CONTAINER" bash -c '
set -e
VER='"$SIGNAL_CLI_VER"'
ARCH=$(uname -m)
INSTALL_DIR=/usr/local
cd /tmp
if command -v signal-cli >/dev/null 2>&1 && signal-cli --version 2>/dev/null | grep -q "$VER"; then
echo " signal-cli $VER already installed"
exit 0
fi
mkdir -p "$INSTALL_DIR/bin"
if [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "amd64" ]; then
echo " Using native binary (x86_64)"
curl -fsSL -o signal-cli.tar.gz \
"https://github.com/AsamK/signal-cli/releases/download/v${VER}/signal-cli-${VER}-Linux-native.tar.gz"
tar xzf signal-cli.tar.gz
mv signal-cli "$INSTALL_DIR/bin/"
else
echo " Using JVM build (${ARCH})"
apt-get update -qq && apt-get install -y -qq openjdk-21-jre-headless
curl -fsSL -o signal-cli.tar.gz \
"https://github.com/AsamK/signal-cli/releases/download/v${VER}/signal-cli-${VER}.tar.gz"
tar xzf signal-cli.tar.gz
cp -a signal-cli-${VER} /opt/signal-cli
ln -sf /opt/signal-cli/bin/signal-cli "$INSTALL_DIR/bin/signal-cli"
fi
chmod +x "$INSTALL_DIR/bin/signal-cli"
rm -rf /tmp/signal-cli*
echo " signal-cli installed"
'
echo ""
echo "Done. Installed:"
echo " - Plugins: ${PLUGINS[*]}"
echo " - signal-cli (for Signal channel)"
echo ""
echo "Restart the gateway to load plugins: docker exec $CONTAINER openclaw gateway restart"

View File

@ -0,0 +1 @@
{"agents":{"defaults":{"model":{"primary":"groq/llama-3.3-70b-versatile"}}}}

View File

@ -0,0 +1 @@
{"gateway":{"controlUi":{"dangerouslyAllowHostHeaderOriginFallback":true}},"agents":{"defaults":{"model":{"primary":"groq/llama-3.3-70b-versatile"}}},"models":{"mode":"merge","providers":{"groq":{"baseUrl":"https://api.groq.com/openai/v1","api":"openai-completions","apiKey":"GROQ_API_KEY_PLACEHOLDER","models":[{"id":"llama-3.3-70b-versatile","name":"Llama 3.3 70B","contextWindow":131072},{"id":"llama-3.1-8b-instant","name":"Llama 3.1 8B","contextWindow":131072}]}}}}