Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
c460ca6
feat: add OpenClaw deployment example and template
GeoSegun May 10, 2026
9fe12af
fix(openclaw): align example with WhatsApp/SSH blog workflow
GeoSegun May 10, 2026
ebf21e3
chore: drop CHANGELOG; shorten OpenClaw recipe description
GeoSegun May 10, 2026
02a50a4
docs(openclaw): shorten README; link saturncloud.io blog post
GeoSegun May 10, 2026
da0c08e
chore(openclaw): add gallery thumbnail asset and wire template URL
GeoSegun May 10, 2026
feda1d6
chore: drop redundant CODEOWNERS entry for openclaw (use catch-all)
GeoSegun May 10, 2026
1be0af5
docs(openclaw): remove gallery thumbnail publishing details from README
GeoSegun May 10, 2026
f358eb2
feat(openclaw): saturn-python 2025.05.01 and large (r5.large 16GB)
GeoSegun May 11, 2026
ac7d7f0
docs(openclaw): fix docs link; clarify skills vs optional setup
GeoSegun May 11, 2026
e2052ff
refactor(openclaw): drop optional skills folder; add _img README for CI
GeoSegun May 11, 2026
a464c29
docs(openclaw): document template gallery thumbnail URL
GeoSegun May 11, 2026
af5957d
docs(openclaw): embed gallery thumbnail URL in recipe description
GeoSegun May 11, 2026
60a96c3
refactor(openclaw): remove _img asset; drop thumbnail from recipe des…
GeoSegun May 11, 2026
c07a55b
ci: use Python 3.11 on GitHub Actions (3.7 unavailable)
GeoSegun May 11, 2026
9be0b92
Revert "ci: use Python 3.11 on GitHub Actions (3.7 unavailable)"
GeoSegun May 11, 2026
d6d9d72
feat(openclaw): enhance deployment setup and configuration
GeoSegun May 11, 2026
32f01cc
fix(openclaw): update deployment description to reflect beta status
GeoSegun May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .saturn/templates-enterprise.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@
"thumbnail_image_url": "https://saturn-public-assets.s3.us-east-2.amazonaws.com/example-thumbnails/weights_and_biases.png",
"weight": 1900,
"recipe_path": "examples/wandb/.saturn/saturn.json"
},
{
"title": "OpenClaw (Deployment)",
"thumbnail_image_url": "https://saturn-public-assets.s3.us-east-2.amazonaws.com/example-thumbnails/openclaw.png",
"weight": 1950,
"recipe_path": "examples/openclaw/.saturn/saturn.json"
}
]
}
6 changes: 6 additions & 0 deletions .saturn/templates-hosted.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@
"thumbnail_image_url": "https://saturn-public-assets.s3.us-east-2.amazonaws.com/example-thumbnails/weights_and_biases.png",
"weight": 1900,
"recipe_path": "examples/wandb/.saturn/saturn.json"
},
{
"title": "OpenClaw (Deployment)",
"thumbnail_image_url": "https://saturn-public-assets.s3.us-east-2.amazonaws.com/example-thumbnails/openclaw.png",
"weight": 1950,
"recipe_path": "examples/openclaw/.saturn/saturn.json"
}
]
}
136 changes: 136 additions & 0 deletions examples/openclaw/.saturn/bootstrap-openclaw.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/usr/bin/env bash
set -eo pipefail

cat > "$HOME/start-openclaw.sh" <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail

echo "[openclaw] starting setup..."

: "${OPENCLAW_GATEWAY_TOKEN:?OPENCLAW_GATEWAY_TOKEN is required}"
: "${OPENCLAW_PUBLIC_ORIGIN:?OPENCLAW_PUBLIC_ORIGIN is required}"

ENABLE_WHATSAPP="${ENABLE_WHATSAPP:-false}"
ENABLE_TELEGRAM="${ENABLE_TELEGRAM:-false}"

ENABLE_WHATSAPP="$(echo "$ENABLE_WHATSAPP" | tr '[:upper:]' '[:lower:]')"
ENABLE_TELEGRAM="$(echo "$ENABLE_TELEGRAM" | tr '[:upper:]' '[:lower:]')"

is_true() {
case "$1" in
true|1|yes|y|on) return 0 ;;
false|0|no|n|off|"") return 1 ;;
*)
echo "[openclaw] invalid boolean value: $1"
echo "[openclaw] use true or false"
exit 1
;;
esac
}

detect_ai_provider() {
if [ -n "${OPENAI_API_KEY:-}" ]; then
AI_AUTH_CHOICE="openai-api-key"
AI_MODEL="${OPENCLAW_MODEL:-openai/gpt-5.5}"
elif [ -n "${ANTHROPIC_API_KEY:-}" ]; then
AI_AUTH_CHOICE="anthropic-api-key"
AI_MODEL="${OPENCLAW_MODEL:-anthropic/claude-sonnet-4-5}"
elif [ -n "${GEMINI_API_KEY:-}" ] || [ -n "${GOOGLE_API_KEY:-}" ]; then
AI_AUTH_CHOICE="gemini-api-key"
AI_MODEL="${OPENCLAW_MODEL:-google/gemini-3.1-pro-preview}"
elif [ -n "${MISTRAL_API_KEY:-}" ]; then
AI_AUTH_CHOICE="mistral-api-key"
AI_MODEL="${OPENCLAW_MODEL:-mistral/mistral-large-latest}"
elif [ -n "${OPENROUTER_API_KEY:-}" ]; then
AI_AUTH_CHOICE="openrouter-api-key"
AI_MODEL="${OPENCLAW_MODEL:-openrouter/auto}"
else
echo "[openclaw] No AI provider API key found."
echo "[openclaw] Set one of: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY, MISTRAL_API_KEY, OPENROUTER_API_KEY."
exit 1
fi

echo "[openclaw] selected auth provider: $AI_AUTH_CHOICE"
echo "[openclaw] selected model: $AI_MODEL"
}

detect_ai_provider

echo "[openclaw] installing OpenClaw..."

curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --no-onboard

echo "[openclaw] installed version:"
openclaw --version

echo "[openclaw] running onboarding..."

openclaw onboard --non-interactive \
--mode local \
--auth-choice "$AI_AUTH_CHOICE" \
--secret-input-mode ref \
--gateway-port 8000 \
--gateway-bind lan \
--gateway-auth token \
--gateway-token-ref-env OPENCLAW_GATEWAY_TOKEN \
--accept-risk \
--skip-health

echo "[openclaw] setting default model..."

openclaw config set agents.defaults.model.primary "$AI_MODEL"

echo "[openclaw] setting allowed origin..."

openclaw config set gateway.controlUi.allowedOrigins "[\"$OPENCLAW_PUBLIC_ORIGIN\"]" --strict-json

echo "[openclaw] disabling Control UI device pairing for template mode..."

openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json

if is_true "$ENABLE_WHATSAPP"; then
echo "[openclaw] configuring WhatsApp..."

: "${WHATSAPP_ALLOW_FROM:?WHATSAPP_ALLOW_FROM is required when ENABLE_WHATSAPP=true}"

openclaw plugins install @openclaw/whatsapp

openclaw config set channels.whatsapp.dmPolicy allowlist
openclaw config set channels.whatsapp.allowFrom "$WHATSAPP_ALLOW_FROM" --strict-json
openclaw config set channels.whatsapp.groupPolicy disabled

echo "[openclaw] WhatsApp configured."
echo "[openclaw] After the UI opens, go to Channels and scan the WhatsApp QR code."
else
echo "[openclaw] WhatsApp disabled."
fi

if is_true "$ENABLE_TELEGRAM"; then
echo "[openclaw] configuring Telegram..."

: "${TELEGRAM_BOT_TOKEN:?TELEGRAM_BOT_TOKEN is required when ENABLE_TELEGRAM=true}"
: "${TELEGRAM_ALLOW_FROM:?TELEGRAM_ALLOW_FROM is required when ENABLE_TELEGRAM=true}"

openclaw config set channels.telegram.enabled true
openclaw config set channels.telegram.botToken "$TELEGRAM_BOT_TOKEN"

openclaw config set channels.telegram.dmPolicy allowlist
openclaw config set channels.telegram.allowFrom "$TELEGRAM_ALLOW_FROM" --strict-json
openclaw config set channels.telegram.groupPolicy disabled

echo "[openclaw] Telegram configured."
echo "[openclaw] Message your Telegram bot from the allowlisted Telegram user ID."
else
echo "[openclaw] Telegram disabled."
fi

echo "[openclaw] starting gateway on port 8000..."

exec openclaw gateway
SCRIPT

chmod +x "$HOME/start-openclaw.sh"

echo "Created $HOME/start-openclaw.sh"

exec "$HOME/start-openclaw.sh"
28 changes: 28 additions & 0 deletions examples/openclaw/.saturn/saturn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "example-openclaw",
"image_uri": "public.ecr.aws/saturncloud/saturn-python:2025.05.01",
"description": "Deploy OpenClaw Beta on Saturn Cloud.",
"environment_variables": {
"ANTHROPIC_API_KEY": "",
"ENABLE_TELEGRAM": "false",
"ENABLE_WHATSAPP": "false",
"OPENCLAW_GATEWAY_TOKEN": "",
"OPENCLAW_MODEL": "anthropic/claude-sonnet-4-5",
"OPENCLAW_PUBLIC_ORIGIN": "https://your-subdomain.community.saturnenterprise.io",
"TELEGRAM_ALLOW_FROM": "[\"123456789\"]",
"TELEGRAM_BOT_TOKEN": "",
"WHATSAPP_ALLOW_FROM": "[\"+1234567890\"]"
},
"working_directory": "/home/jovyan/examples/examples/openclaw",
"git_repositories": [
{
"url": "https://github.com/saturncloud/examples",
"path": "/home/jovyan/examples"
}
],
"deployment": {
"instance_type": "large",
"command": "bash .saturn/bootstrap-openclaw.sh"
},
"version": "2022.01.06"
}
54 changes: 54 additions & 0 deletions examples/openclaw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# OpenClaw on Saturn Cloud

This example runs [OpenClaw](https://docs.openclaw.ai/) as a **Deployment**: on start it installs OpenClaw (once), applies onboarding and configuration from environment variables, then runs `openclaw gateway` on port **8000**. The recipe uses **`saturn-python:2025.05.01`** and instance size **`large`** (AWS **r5.large**: 2 vCPU, 16 GB RAM).

For the full guide (resource options, QR flows, troubleshooting), see:

[https://saturncloud.io/blog/how-to-deploy-openclaw-on-saturncloud/](https://saturncloud.io/blog/how-to-deploy-openclaw-on-saturncloud/)

## Startup

`deployment.command`: **`bash .saturn/bootstrap-openclaw.sh`** (runs from **`working_directory`**).

## Environment variables

Set values in the deployment **Details** (never commit secrets).

### Required

| Variable | Description |
|----------|-------------|
| `OPENCLAW_GATEWAY_TOKEN` | Gateway authentication token (`--gateway-token-ref-env`). |
| `OPENCLAW_PUBLIC_ORIGIN` | Control UI allowed origin, e.g. `https://your-subdomain.community.saturnenterprise.io`. |

### AI provider

Set **one** API key; that determines the provider. Optional model override: **`OPENCLAW_MODEL`**.

| Variable | Description |
|----------|-------------|
| `OPENAI_API_KEY` | OpenAI (`openai-api-key`). |
| `ANTHROPIC_API_KEY` | Anthropic (`anthropic-api-key`). |
| `GEMINI_API_KEY` or `GOOGLE_API_KEY` | Gemini (`gemini-api-key`). |
| `MISTRAL_API_KEY` | Mistral (`mistral-api-key`). |
| `OPENROUTER_API_KEY` | OpenRouter (`openrouter-api-key`). |
| `OPENCLAW_MODEL` | Primary model id (defaults depend on provider if unset). |

### WhatsApp (optional)

When **`ENABLE_WHATSAPP=true`**:

| Variable | Description |
|----------|-------------|
| `ENABLE_WHATSAPP` | `true` / `false`. |
| `WHATSAPP_ALLOW_FROM` | JSON array string, e.g. `["+1234567890"]`. |

### Telegram (optional)

When **`ENABLE_TELEGRAM=true`**:

| Variable | Description |
|----------|-------------|
| `ENABLE_TELEGRAM` | `true` / `false`. |
| `TELEGRAM_BOT_TOKEN` | Bot token from BotFather. |
| `TELEGRAM_ALLOW_FROM` | JSON array string, e.g. `["123456789"]`. |
Loading