- Introduced Azure OpenAI provider configuration in `azure-openai-provider.ts`. - Implemented global fetch wrapper to handle Azure API versioning. - Added new session files for Azure OpenAI interactions. - Created initial configuration files for cron jobs and device management. - Established Docker Compose setup for Azure OpenAI deployment. - Updated main session management with new skills and context handling. - Added environment variable resolution for Azure OpenAI configuration.
11 KiB
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
RESOURCE_GROUP="moltbot-rg"
LOCATION="eastus2"
az group create --name $RESOURCE_GROUP --location $LOCATION
1.2 Create Azure Container Registry (ACR)
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
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-5.2):
az cognitiveservices account deployment create \
--name $OPENAI_NAME \
--resource-group $RESOURCE_GROUP \
--deployment-name "gpt-5.2" \
--model-name "gpt-5.2" \
--model-version "2024-07-18" \
--model-format OpenAI \
--sku-capacity 10 \
--sku-name Standard
Get the endpoint and key:
# 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
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
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:
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-5.2"}}}}' > /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)
az acr build \
--registry $ACR_NAME \
--image moltbot-azure:latest \
--file Dockerfile.azure \
.
3.2 Alternative: Build Locally and Push
# 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
# 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
# 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_DEPLOYMENT_NAME="gpt-5.2" \
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
az webapp config set \
--resource-group $RESOURCE_GROUP \
--name $WEB_APP_NAME \
--web-sockets-enabled true \
--always-on true
4.4 Set Startup Command
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
az webapp restart --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME
5.2 Check Logs
# 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-5.2
[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:
- Ensure
dangerouslyDisableDeviceAuth: trueis in the config - Ensure
trustedProxiesincludes169.254.0.0/16 - 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 malformedSyntaxError- Config JSON is invalid- Port binding errors - Ensure
WEBSITES_PORT=18789
Common fix: Verify appCommandLine is set correctly:
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:
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:
- Model deployment name matches config (e.g.,
gpt-5.2) - API key is correct
- Endpoint URL format:
https://<resource>.openai.azure.com/ - 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
- Use Managed Identity instead of API keys where possible
- Restrict network access with Azure Private Endpoints
- Enable HTTPS Only in Web App settings
- Rotate gateway tokens periodically
- Use Azure Key Vault for secrets in production
Updating the Deployment
To deploy a new version:
# 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:
az group delete --name $RESOURCE_GROUP --yes --no-wait