Docs: Azure disable Control UI pairing
This commit is contained in:
parent
9c0c2cb2fa
commit
a0c62d96c2
1
.gitignore
vendored
1
.gitignore
vendored
@ -65,6 +65,7 @@ apps/ios/*.mobileprovision
|
|||||||
# Local untracked files
|
# Local untracked files
|
||||||
.local/
|
.local/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
data/
|
||||||
IDENTITY.md
|
IDENTITY.md
|
||||||
USER.md
|
USER.md
|
||||||
.tgz
|
.tgz
|
||||||
|
|||||||
47
Dockerfile.azure
Normal file
47
Dockerfile.azure
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
FROM node:22-bookworm
|
||||||
|
|
||||||
|
# Install Bun (required for build scripts)
|
||||||
|
RUN curl -fsSL https://bun.sh/install | bash
|
||||||
|
ENV PATH="/root/.bun/bin:${PATH}"
|
||||||
|
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ARG CLAWDBOT_DOCKER_APT_PACKAGES=""
|
||||||
|
RUN if [ -n "$CLAWDBOT_DOCKER_APT_PACKAGES" ]; then \
|
||||||
|
apt-get update && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $CLAWDBOT_DOCKER_APT_PACKAGES && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
|
||||||
|
COPY ui/package.json ./ui/package.json
|
||||||
|
COPY patches ./patches
|
||||||
|
COPY scripts ./scripts
|
||||||
|
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN CLAWDBOT_A2UI_SKIP_MISSING=1 pnpm build
|
||||||
|
# Force pnpm for UI build (Bun may fail on ARM/Synology architectures)
|
||||||
|
ENV CLAWDBOT_PREFER_PNPM=1
|
||||||
|
RUN pnpm ui:install
|
||||||
|
RUN pnpm ui:build
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
# Security hardening: Run as non-root user
|
||||||
|
# The node:22-bookworm image includes a 'node' user (uid 1000)
|
||||||
|
# This reduces the attack surface by preventing container escape via root privileges
|
||||||
|
|
||||||
|
# Create default config for Azure deployment (Control UI token-only + trust Azure proxy)
|
||||||
|
RUN mkdir -p /home/node/.moltbot && \
|
||||||
|
echo '{"gateway":{"controlUi":{"allowInsecureAuth":true},"trustedProxies":["169.254.0.0/16"]},"agents":{"defaults":{"model":{"primary":"azure-openai/gpt-4o-mini"}}}}' > /home/node/.moltbot/moltbot.json && \
|
||||||
|
chown -R node:node /home/node/.moltbot
|
||||||
|
|
||||||
|
USER node
|
||||||
|
|
||||||
|
# Azure Web App startup command
|
||||||
|
CMD ["node", "dist/index.js", "gateway", "--bind", "lan", "--port", "18789", "--allow-unconfigured"]
|
||||||
390
docs/platforms/azure/deploy-guide.md
Normal file
390
docs/platforms/azure/deploy-guide.md
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
# Deploying Moltbot to Azure Web App for Containers
|
||||||
|
|
||||||
|
This guide covers deploying Moltbot gateway to Azure Web App for Containers with Azure OpenAI as the LLM provider.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Azure CLI installed and authenticated (`az login`)
|
||||||
|
- Docker (for local testing, optional)
|
||||||
|
- An Azure subscription with permissions to create resources
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Azure Web App │
|
||||||
|
│ ┌─────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Container (Node.js) │ │
|
||||||
|
│ │ ┌─────────────────────────────────────────────┐ │ │
|
||||||
|
│ │ │ Moltbot Gateway │ │ │
|
||||||
|
│ │ │ - Control UI (WebSocket) │ │ │
|
||||||
|
│ │ │ - Agent runtime │ │ │
|
||||||
|
│ │ └─────────────────────────────────────────────┘ │ │
|
||||||
|
│ └─────────────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Azure OpenAI │
|
||||||
|
│ - GPT-5.2, GPT-5.2-codex, etc. │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 1: Create Azure Resources
|
||||||
|
|
||||||
|
### 1.1 Create Resource Group
|
||||||
|
|
||||||
|
```bash
|
||||||
|
RESOURCE_GROUP="moltbot-rg"
|
||||||
|
LOCATION="eastus2"
|
||||||
|
|
||||||
|
az group create --name $RESOURCE_GROUP --location $LOCATION
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 Create Azure Container Registry (ACR)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ACR_NAME="moltbotreg" # Must be globally unique
|
||||||
|
|
||||||
|
az acr create \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--name $ACR_NAME \
|
||||||
|
--sku Basic \
|
||||||
|
--admin-enabled true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 Create Azure OpenAI Resource
|
||||||
|
|
||||||
|
```bash
|
||||||
|
OPENAI_NAME="moltbot-openai"
|
||||||
|
|
||||||
|
az cognitiveservices account create \
|
||||||
|
--name $OPENAI_NAME \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--location $LOCATION \
|
||||||
|
--kind OpenAI \
|
||||||
|
--sku S0
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy a model (e.g., gpt-4o-mini):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az cognitiveservices account deployment create \
|
||||||
|
--name $OPENAI_NAME \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--deployment-name "gpt-4o-mini" \
|
||||||
|
--model-name "gpt-4o-mini" \
|
||||||
|
--model-version "2024-07-18" \
|
||||||
|
--model-format OpenAI \
|
||||||
|
--sku-capacity 10 \
|
||||||
|
--sku-name Standard
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the endpoint and key:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Endpoint
|
||||||
|
az cognitiveservices account show \
|
||||||
|
--name $OPENAI_NAME \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--query properties.endpoint -o tsv
|
||||||
|
|
||||||
|
# Key
|
||||||
|
az cognitiveservices account keys list \
|
||||||
|
--name $OPENAI_NAME \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--query key1 -o tsv
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 Create App Service Plan
|
||||||
|
|
||||||
|
```bash
|
||||||
|
APP_SERVICE_PLAN="moltbot-plan"
|
||||||
|
|
||||||
|
az appservice plan create \
|
||||||
|
--name $APP_SERVICE_PLAN \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--location $LOCATION \
|
||||||
|
--is-linux \
|
||||||
|
--sku B1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.5 Create Web App
|
||||||
|
|
||||||
|
```bash
|
||||||
|
WEB_APP_NAME="moltbot-app" # Must be globally unique
|
||||||
|
|
||||||
|
az webapp create \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--plan $APP_SERVICE_PLAN \
|
||||||
|
--name $WEB_APP_NAME \
|
||||||
|
--deployment-container-image-name "${ACR_NAME}.azurecr.io/moltbot-azure:latest"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2: Configure the Dockerfile
|
||||||
|
|
||||||
|
Create `Dockerfile.azure` in the repository root:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
FROM node:22-bookworm
|
||||||
|
|
||||||
|
# Install bun for faster builds
|
||||||
|
RUN curl -fsSL https://bun.sh/install | bash
|
||||||
|
ENV PATH="/root/.bun/bin:${PATH}"
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY package.json pnpm-lock.yaml ./
|
||||||
|
COPY patches ./patches
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
# Copy source and build
|
||||||
|
COPY . .
|
||||||
|
RUN pnpm build
|
||||||
|
|
||||||
|
# Prune dev dependencies
|
||||||
|
RUN pnpm prune --prod
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
# Create config directory and bake in Azure-specific config
|
||||||
|
# IMPORTANT: trustedProxies is required for Azure's internal proxy
|
||||||
|
RUN mkdir -p /home/node/.moltbot && \
|
||||||
|
echo '{"gateway":{"controlUi":{"allowInsecureAuth":true},"trustedProxies":["169.254.0.0/16"]},"agents":{"defaults":{"model":{"primary":"azure-openai/gpt-4o-mini"}}}}' > /home/node/.moltbot/moltbot.json && \
|
||||||
|
chown -R node:node /home/node/.moltbot
|
||||||
|
|
||||||
|
USER node
|
||||||
|
|
||||||
|
EXPOSE 18789
|
||||||
|
|
||||||
|
CMD ["node", "dist/index.js", "gateway", "--bind", "lan", "--port", "18789", "--allow-unconfigured"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Configuration Notes
|
||||||
|
|
||||||
|
| Setting | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `allowInsecureAuth: true` | Control UI uses token-only auth (skips device pairing). Security downgrade; prefer HTTPS + pairing when possible. |
|
||||||
|
| `trustedProxies: ["169.254.0.0/16"]` | Trust Azure's internal proxy for `X-Forwarded-*` headers |
|
||||||
|
| `--bind lan` | Bind to all interfaces (required for container networking) |
|
||||||
|
| `--allow-unconfigured` | Start without requiring pre-configured channels |
|
||||||
|
|
||||||
|
## Step 3: Build and Push Container Image
|
||||||
|
|
||||||
|
### 3.1 Build with ACR Tasks (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az acr build \
|
||||||
|
--registry $ACR_NAME \
|
||||||
|
--image moltbot-azure:latest \
|
||||||
|
--file Dockerfile.azure \
|
||||||
|
.
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Alternative: Build Locally and Push
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Login to ACR
|
||||||
|
az acr login --name $ACR_NAME
|
||||||
|
|
||||||
|
# Build
|
||||||
|
docker build -t ${ACR_NAME}.azurecr.io/moltbot-azure:latest -f Dockerfile.azure .
|
||||||
|
|
||||||
|
# Push
|
||||||
|
docker push ${ACR_NAME}.azurecr.io/moltbot-azure:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 4: Configure Web App
|
||||||
|
|
||||||
|
### 4.1 Connect ACR to Web App
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get ACR credentials
|
||||||
|
ACR_USERNAME=$(az acr credential show --name $ACR_NAME --query username -o tsv)
|
||||||
|
ACR_PASSWORD=$(az acr credential show --name $ACR_NAME --query passwords[0].value -o tsv)
|
||||||
|
|
||||||
|
# Configure container settings
|
||||||
|
az webapp config container set \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--name $WEB_APP_NAME \
|
||||||
|
--docker-custom-image-name "${ACR_NAME}.azurecr.io/moltbot-azure:latest" \
|
||||||
|
--docker-registry-server-url "https://${ACR_NAME}.azurecr.io" \
|
||||||
|
--docker-registry-server-user $ACR_USERNAME \
|
||||||
|
--docker-registry-server-password $ACR_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 Configure Environment Variables
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate a secure gateway token
|
||||||
|
GATEWAY_TOKEN=$(openssl rand -hex 16)
|
||||||
|
|
||||||
|
az webapp config appsettings set \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--name $WEB_APP_NAME \
|
||||||
|
--settings \
|
||||||
|
WEBSITES_PORT=18789 \
|
||||||
|
MOLTBOT_STATE_DIR=/home/node/.moltbot \
|
||||||
|
MOLTBOT_CONFIG_PATH=/home/node/.moltbot/moltbot.json \
|
||||||
|
CLAWDBOT_GATEWAY_TOKEN=$GATEWAY_TOKEN \
|
||||||
|
AZURE_OPENAI_API_KEY="<your-azure-openai-key>" \
|
||||||
|
AZURE_OPENAI_ENDPOINT="https://<your-resource>.openai.azure.com/" \
|
||||||
|
AZURE_OPENAI_API_VERSION="2024-08-01-preview"
|
||||||
|
|
||||||
|
echo "Gateway Token: $GATEWAY_TOKEN"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 Enable WebSockets and Always On
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az webapp config set \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--name $WEB_APP_NAME \
|
||||||
|
--web-sockets-enabled true \
|
||||||
|
--always-on true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 Set Startup Command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az webapp config set \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--name $WEB_APP_NAME \
|
||||||
|
--startup-file 'node dist/index.js gateway --bind lan --port 18789 --allow-unconfigured'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 5: Deploy and Verify
|
||||||
|
|
||||||
|
### 5.1 Restart the Web App
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az webapp restart --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Check Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stream logs
|
||||||
|
az webapp log tail --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME
|
||||||
|
|
||||||
|
# Or download logs
|
||||||
|
az webapp log download \
|
||||||
|
--resource-group $RESOURCE_GROUP \
|
||||||
|
--name $WEB_APP_NAME \
|
||||||
|
--log-file /tmp/webapp-logs.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 Verify Deployment
|
||||||
|
|
||||||
|
Look for these indicators in the logs:
|
||||||
|
|
||||||
|
```
|
||||||
|
[gateway] agent model: azure-openai/gpt-4o-mini
|
||||||
|
[gateway] listening on 0.0.0.0:18789
|
||||||
|
```
|
||||||
|
|
||||||
|
If you see warnings about untrusted proxy headers, the `trustedProxies` config is not applied correctly.
|
||||||
|
|
||||||
|
### 5.4 Access Control UI
|
||||||
|
|
||||||
|
Open in browser:
|
||||||
|
|
||||||
|
```
|
||||||
|
https://<your-app-name>.azurewebsites.net/?token=<your-gateway-token>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Problem: "pairing required" Error
|
||||||
|
|
||||||
|
**Cause**: The gateway doesn't recognize the connection as authorized.
|
||||||
|
|
||||||
|
**Solutions**:
|
||||||
|
1. Ensure `dangerouslyDisableDeviceAuth: true` is in the config
|
||||||
|
2. Ensure `trustedProxies` includes `169.254.0.0/16`
|
||||||
|
3. Access with the token: `?token=<your-token>`
|
||||||
|
|
||||||
|
### Problem: "Proxy headers detected from untrusted address"
|
||||||
|
|
||||||
|
**Cause**: Azure's internal proxy IP is not trusted.
|
||||||
|
|
||||||
|
**Solution**: Add `"trustedProxies": ["169.254.0.0/16"]` to gateway config.
|
||||||
|
|
||||||
|
### Problem: Container Crash Loop
|
||||||
|
|
||||||
|
**Check logs for**:
|
||||||
|
- `Cannot find module` - Startup command is malformed
|
||||||
|
- `SyntaxError` - Config JSON is invalid
|
||||||
|
- Port binding errors - Ensure `WEBSITES_PORT=18789`
|
||||||
|
|
||||||
|
**Common fix**: Verify `appCommandLine` is set correctly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az webapp config show -g $RESOURCE_GROUP -n $WEB_APP_NAME --query appCommandLine
|
||||||
|
```
|
||||||
|
|
||||||
|
If it shows `""` (empty quotes), the image CMD won't be used. Set it explicitly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az webapp config set -g $RESOURCE_GROUP -n $WEB_APP_NAME \
|
||||||
|
--startup-file 'node dist/index.js gateway --bind lan --port 18789 --allow-unconfigured'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problem: Azure OpenAI Not Working
|
||||||
|
|
||||||
|
**Verify**:
|
||||||
|
1. Model deployment name matches config (e.g., `gpt-4o-mini`)
|
||||||
|
2. API key is correct
|
||||||
|
3. Endpoint URL format: `https://<resource>.openai.azure.com/`
|
||||||
|
4. API version is supported (e.g., `2024-08-01-preview`)
|
||||||
|
|
||||||
|
### Problem: 503 Service Unavailable
|
||||||
|
|
||||||
|
**Causes**:
|
||||||
|
- Container still starting (wait 1-2 minutes)
|
||||||
|
- Container crashing (check logs)
|
||||||
|
- Port mismatch (verify `WEBSITES_PORT`)
|
||||||
|
|
||||||
|
## Environment Variables Reference
|
||||||
|
|
||||||
|
| Variable | Required | Description |
|
||||||
|
|----------|----------|-------------|
|
||||||
|
| `WEBSITES_PORT` | Yes | Port the container listens on (18789) |
|
||||||
|
| `MOLTBOT_STATE_DIR` | Yes | Directory for runtime state |
|
||||||
|
| `MOLTBOT_CONFIG_PATH` | Yes | Path to config JSON file |
|
||||||
|
| `CLAWDBOT_GATEWAY_TOKEN` | Yes | Token for Control UI authentication |
|
||||||
|
| `AZURE_OPENAI_API_KEY` | Yes | Azure OpenAI API key |
|
||||||
|
| `AZURE_OPENAI_ENDPOINT` | Yes | Azure OpenAI endpoint URL |
|
||||||
|
| `AZURE_OPENAI_API_VERSION` | Yes | API version (e.g., 2024-08-01-preview) |
|
||||||
|
|
||||||
|
## Security Recommendations
|
||||||
|
|
||||||
|
1. **Use Managed Identity** instead of API keys where possible
|
||||||
|
2. **Restrict network access** with Azure Private Endpoints
|
||||||
|
3. **Enable HTTPS Only** in Web App settings
|
||||||
|
4. **Rotate gateway tokens** periodically
|
||||||
|
5. **Use Azure Key Vault** for secrets in production
|
||||||
|
|
||||||
|
## Updating the Deployment
|
||||||
|
|
||||||
|
To deploy a new version:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Rebuild image
|
||||||
|
az acr build --registry $ACR_NAME --image moltbot-azure:latest --file Dockerfile.azure .
|
||||||
|
|
||||||
|
# Restart to pull new image
|
||||||
|
az webapp restart --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cleanup
|
||||||
|
|
||||||
|
To remove all resources:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
az group delete --name $RESOURCE_GROUP --yes --no-wait
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue
Block a user