A production-ready Docker setup for AI agent gateways. Supports:
- OpenClaw - The official self-hosted AI agent gateway
- PicoClaw - Sipeed's lightweight AI agent gateway for embedded devices
- IronClaw - NEAR AI's blockchain-integrated AI agent gateway
- ZeroClaw - ZeroClaw Labs' AI agent gateway
- Debian Bookworm (LTS) Base - Stable and secure foundation
- Multi-Architecture Support - AMD64 builds
- Multiple Upstream Support - Choose between OpenClaw, PicoClaw, IronClaw, or ZeroClaw
- Environment Variable Configuration - Configure everything via
.envfile - Persistent Data Storage - Config, sessions, skills, plugins, and npm packages survive container restarts
- Nginx Reverse Proxy - Built-in authentication and rate limiting
- Browser Automation - Optional Chrome sidecar for web automation
- Health Checks & Auto-Restart - Designed for 24/7 operation
- Security Hardened - Non-root user, minimal capabilities, security headers
git clone https://github.com/xfanth/polyclaw.git
cd polyclawcp .env.example .env
# Edit .env with your favorite editor
nano .envAt minimum, you need to set:
UPSTREAM=openclaworUPSTREAM=picoclaw(choose your upstream)- One AI provider API key (e.g.,
ANTHROPIC_API_KEY,KIMI_API_KEY,OPENROUTER_API_KEY) AUTH_PASSWORDfor web UI protectionOPENCLAW_GATEWAY_TOKENfor API access
docker compose up -dOpen your browser to http://localhost:8080 and log in with:
- Username:
admin(or yourAUTH_USERNAME) - Password: Your
AUTH_PASSWORD
This Docker setup supports four upstream projects:
The official self-hosted AI agent gateway that connects your favorite chat apps to AI coding agents.
UPSTREAM=openclaw
UPSTREAM_VERSION=main- GitHub: https://github.com/openclaw/openclaw
- Documentation: https://docs.openclaw.ai/
- Community: Discord
Sipeed's lightweight AI agent gateway, optimized for embedded devices and resource-constrained environments.
UPSTREAM=picoclaw
UPSTREAM_VERSION=main- GitHub: https://github.com/sipeed/picoclaw
- Ideal for: MAIX devices, embedded systems, lightweight deployments
NEAR AI's AI agent gateway with blockchain integration capabilities.
UPSTREAM=ironclaw
UPSTREAM_VERSION=main- GitHub: https://github.com/nearai/ironclaw
- Ideal for: Blockchain-integrated AI applications
ZeroClaw Labs' AI agent gateway.
UPSTREAM=zeroclaw
UPSTREAM_VERSION=mainSimply change the UPSTREAM variable in your .env file:
UPSTREAM=openclaw
UPSTREAM_VERSION=mainThen restart the container:
docker compose down
docker compose up -dAt least one AI provider API key is required:
| Provider | Environment Variable |
|---|---|
| Anthropic | ANTHROPIC_API_KEY |
| OpenAI | OPENAI_API_KEY |
| OpenRouter | OPENROUTER_API_KEY |
| Google Gemini | GEMINI_API_KEY |
| xAI (Grok) | XAI_API_KEY |
| Groq | GROQ_API_KEY |
| Mistral | MISTRAL_API_KEY |
| Cerebras | CEREBRAS_API_KEY |
| Venice | VENICE_API_KEY |
| Moonshot | MOONSHOT_API_KEY |
| Moonshot Kimi | KIMI_API_KEY |
| Minimax | MINIMAX_API_KEY |
| Z.AI | ZAI_API_KEY |
| OpenCode | OPENCODE_API_KEY |
| AI Gateway | AI_GATEWAY_API_KEY |
| Synthetic | SYNTHETIC_API_KEY |
| Xiaomi | XIAOMI_API_KEY |
| GitHub Copilot | COPILOT_GITHUB_TOKEN |
| AWS Bedrock | AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY |
| Ollama (local) | OLLAMA_BASE_URL |
Set your preferred model:
OPENCLAW_PRIMARY_MODEL=anthropic/claude-sonnet-4-5-20250929Popular options:
anthropic/claude-sonnet-4-5-20250929- Claude Sonnet 4.5anthropic/claude-opus-4-5-20250929- Claude Opus 4.5openrouter/anthropic/claude-opus-4-5- Claude via OpenRoutergoogle/gemini-2.5-pro- Gemini Proopencode/kimi-k2.5- Kimi K2.5zai/glm-4.7- Z.AI GLM-4.7
Configure fallback models for when the primary model fails:
OPENCLAW_FALLBACK_MODELS=openrouter/anthropic/claude-opus-4-5,google/gemini-2.5-proConfigure models for image generation:
OPENCLAW_IMAGE_MODEL_PRIMARY=openai/gpt-4o-image
OPENCLAW_IMAGE_MODEL_FALLBACKS=openai/dall-e-3,stability-ai/stable-diffusionThe following directories are persisted (configurable via .env):
| Host Path (default) | Container Path | Contents |
|---|---|---|
./data/.openclaw |
/data/.openclaw |
Config, sessions, skills, plugins |
./data/workspace |
/data/workspace |
Agent projects |
./logs |
/var/log/openclaw |
Application logs |
Configure via environment variables:
OPENCLAW_DATA_DIR=./data/.openclaw
OPENCLAW_WORKSPACE_DIR=./data/workspace
OPENCLAW_LOGS_DIR=./logsWHATSAPP_ENABLED=true
WHATSAPP_DM_POLICY=pairing
WHATSAPP_ALLOW_FROM=+1234567890,+0987654321
WHATSAPP_GROUP_POLICY=allowlist
WHATSAPP_GROUP_ALLOW_FROM=group-id-1@g.usWhen enabled, scan the QR code in the logs to pair:
docker compose logs -f gatewayTELEGRAM_BOT_TOKEN=your-bot-token-from-botfather
TELEGRAM_DM_POLICY=pairing
TELEGRAM_ALLOW_FROM=username1,username2DISCORD_BOT_TOKEN=your-bot-token
DISCORD_DM_POLICY=pairing
DISCORD_DM_ALLOW_FROM=user-id-1,user-id-2SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
SLACK_DM_POLICY=pairing
SLACK_GROUP_POLICY=openEnable browser automation with the included Chrome sidecar:
BROWSER_CDP_URL=http://browser:9222
BROWSER_DEFAULT_PROFILE=openclaw
BROWSER_EVALUATE_ENABLED=trueAccess the browser desktop via noVNC at http://localhost:6080/vnc.html
Note: The browser sidecar exposes noVNC on port 6080 and Chrome DevTools Protocol on port 9222. These ports are mapped to the host by default.
Example browser image that includes noVNC on port 6080:
ghcr.io/xfanth/cdp_vnc_browser:latest
When using a custom browser image, ensure it exposes noVNC on port 6080.
Enable webhook automation:
HOOKS_ENABLED=true
HOOKS_TOKEN=your-secret-hook-tokenTrigger actions via:
curl -X POST http://localhost:8080/hooks/wake \
-H "Authorization: Bearer your-secret-hook-token"services:
gateway:
image: ghcr.io/xfanth/openclaw:latest
ports:
- "8080:8080"
environment:
- UPSTREAM=openclaw
- ANTHROPIC_API_KEY=sk-ant-...
- AUTH_PASSWORD=secure-password
- OPENCLAW_GATEWAY_TOKEN=your-token
volumes:
- ./data:/data/.openclaw
restart: unless-stoppedservices:
gateway:
image: ghcr.io/xfanth/picoclaw:latest
ports:
- "8080:8080"
environment:
- UPSTREAM=picoclaw
- ANTHROPIC_API_KEY=sk-ant-...
- AUTH_PASSWORD=secure-password
- OPENCLAW_GATEWAY_TOKEN=your-token
volumes:
- ./data:/data/.picoclaw
restart: unless-stoppedservices:
gateway:
image: ghcr.io/xfanth/ironclaw:latest
ports:
- "8080:8080"
environment:
- UPSTREAM=ironclaw
- ANTHROPIC_API_KEY=sk-ant-...
- AUTH_PASSWORD=secure-password
- OPENCLAW_GATEWAY_TOKEN=your-token
volumes:
- ./data:/data/.ironclaw
restart: unless-stoppedservices:
gateway:
image: ghcr.io/xfanth/zeroclaw:latest
ports:
- "8080:8080"
environment:
- UPSTREAM=zeroclaw
- ANTHROPIC_API_KEY=sk-ant-...
- AUTH_PASSWORD=secure-password
- OPENCLAW_GATEWAY_TOKEN=your-token
volumes:
- ./data:/data/.zeroclaw
restart: unless-stoppedSee the included docker-compose.yml for a complete example with:
- Browser automation sidecar
- All channel integrations
- Persistent volumes
- Health checks
- Resource limits
services:
gateway:
image: ghcr.io/xfanth/${UPSTREAM:-openclaw}:latest
# ... rest of configurationservices:
gateway:
build:
context: .
dockerfile: Dockerfile
args:
UPSTREAM: ${UPSTREAM:-openclaw}
UPSTREAM_VERSION: ${UPSTREAM_VERSION:-main}
# ... rest of configuration| Variable | Description | Default |
|---|---|---|
UPSTREAM |
Which upstream to use (openclaw or picoclaw) |
openclaw |
UPSTREAM_VERSION |
Version/branch to build | main |
| Variable | Description | Default |
|---|---|---|
ANTHROPIC_API_KEY or other provider |
AI provider API key | - |
AUTH_PASSWORD |
Web UI password | - |
OPENCLAW_GATEWAY_TOKEN |
Gateway API token | Auto-generated |
| Variable | Description | Default |
|---|---|---|
AUTH_USERNAME |
Web UI username | admin |
AUTH_PASSWORD |
Web UI password | - |
| Variable | Description | Default |
|---|---|---|
OPENCLAW_GATEWAY_TOKEN |
Bearer token for API | Auto-generated |
OPENCLAW_EXTERNAL_GATEWAY_PORT |
External port (nginx, callers use this) | 8080 |
OPENCLAW_INTERNAL_GATEWAY_PORT |
Internal port (gateway binary) | 18789 |
OPENCLAW_GATEWAY_BIND |
Bind mode (loopback/lan) | loopback |
| Variable | Description | Default |
|---|---|---|
OPENCLAW_PRIMARY_MODEL |
Primary text model | - |
OPENCLAW_FALLBACK_MODELS |
Comma-separated fallback models | - |
OPENCLAW_IMAGE_MODEL_PRIMARY |
Primary image generation model | - |
OPENCLAW_IMAGE_MODEL_FALLBACKS |
Comma-separated fallback image models | - |
| Variable | Description | Default |
|---|---|---|
OPENCLAW_DATA_DIR |
Host path for data | ./data/.openclaw |
OPENCLAW_WORKSPACE_DIR |
Host path for workspace | ./data/workspace |
OPENCLAW_LOGS_DIR |
Host path for logs | ./logs |
| Variable | Description | Default |
|---|---|---|
BROWSER_CDP_URL |
Chrome DevTools URL | - |
BROWSER_DEFAULT_PROFILE |
Browser profile name | - |
BROWSER_EVALUATE_ENABLED |
Enable JS evaluation | false |
BROWSER_VNC_PORT |
noVNC port on host | 6080 |
BROWSER_CDP_PORT |
Chrome DevTools port on host | 9222 |
| Variable | Description | Default |
|---|---|---|
HOOKS_ENABLED |
Enable webhooks | false |
HOOKS_TOKEN |
Webhook auth token | - |
HOOKS_PATH |
Webhook path prefix | /hooks |
| Variable | Description | Default |
|---|---|---|
WHATSAPP_ENABLED |
Enable WhatsApp | false |
WHATSAPP_DM_POLICY |
DM policy | pairing |
WHATSAPP_ALLOW_FROM |
Allowed phone numbers | - |
WHATSAPP_GROUP_POLICY |
Group policy | - |
| Variable | Description | Default |
|---|---|---|
TZ |
Timezone | UTC |
The image includes an auto-update workflow that checks for new releases daily and rebuilds automatically.
# Pull latest image
docker compose pull
# Recreate containers
docker compose up -d
# View logs
docker compose logs -f gatewayYour data is persisted in volumes, so updates are safe:
# Stop containers
docker compose down
# Pull latest
docker compose pull
# Start with new version
docker compose up -dCheck logs:
docker compose logs -f gatewayCommon issues:
- Missing API key: Set at least one provider API key
- Missing auth password: Set
AUTH_PASSWORDfor production
- Check that
WHATSAPP_ENABLED=trueis set - View logs to see QR code:
docker compose logs -f gateway - Scan QR code with WhatsApp mobile app
- Ensure browser sidecar is running:
docker compose ps - Check
BROWSER_CDP_URL=http://browser:9222is set - Verify network connectivity:
docker compose exec gateway curl http://browser:9222/json/version
If you see permission errors:
# Fix ownership (Gateway runs as UID/GID 10000)
sudo chown -R 10000:10000 ./data
# Or run as root (not recommended for production)
docker compose exec --user root gateway bashTo start fresh:
# Stop and remove containers
docker compose down
# Remove data (WARNING: This deletes all configuration!)
sudo rm -rf ./data
# Start fresh
docker compose up -d- Always set
AUTH_PASSWORDfor production deployments - Use strong
OPENCLAW_GATEWAY_TOKEN(generate withopenssl rand -hex 32) - Keep API keys in
.envfile - never commit them - Use HTTPS in production (put behind reverse proxy with SSL)
- Restrict WhatsApp/Telegram allowlists to known contacts
- Regularly update the Docker image for security patches
# Clone repository
git clone https://github.com/xfanth/polyclaw.git
cd polyclaw
# Build OpenClaw image
docker build -t openclaw:local .
# Or build PicoClaw image
docker build --build-arg UPSTREAM=picoclaw -t picoclaw:local .
# Or build with specific version
docker build --build-arg UPSTREAM=openclaw --build-arg UPSTREAM_VERSION=v2026.2.1 -t openclaw:local .This project includes a comprehensive test suite using Python and pytest.
# Install dependencies with uv
uv sync
# Run all tests
uv run pytest
# Run only unit tests
uv run pytest tests/unit -v
# Run with coverage
uv run pytest --cov=lib tests/tests/unit/- Unit tests for configuration modulestests/integration/- Integration tests for GitHub API and Dockerfile validation
This repository includes GitHub Actions workflows for:
- Docker Build and Push - Builds and pushes multi-arch images on every push to main
- Auto-Update Check - Daily check for new releases
- Security Scanning - Trivy vulnerability scanning
Images are published to:
ghcr.io/xfanth/openclaw:latestghcr.io/xfanth/openclaw:<version>ghcr.io/xfanth/picoclaw:latestghcr.io/xfanth/picoclaw:<version>ghcr.io/xfanth/ironclaw:latestghcr.io/xfanth/ironclaw:<version>ghcr.io/xfanth/zeroclaw:latestghcr.io/xfanth/zeroclaw:<version>
MIT License - see LICENSE for details.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
We use pre-commit to ensure code quality and consistency. To set it up:
pip install pre-commit
pre-commit installPre-commit hooks will run automatically before each commit. To run them manually:
pre-commit run --all-filesThe hooks include:
- YAML syntax validation
- Shell script linting
- Dockerfile linting
- Trailing whitespace cleanup
- File size checks
- Merge conflict detection
- OpenClaw - The official AI agent gateway
- PicoClaw - Sipeed's lightweight AI agent gateway
- IronClaw - NEAR AI's blockchain-integrated AI agent gateway
- ZeroClaw - ZeroClaw Labs' AI agent gateway
- coollabsio/openclaw - Inspiration for Docker setup