Running OpenClaw in Docker introduces networking quirks that make gateway.controlui.allowedOrigins configuration tricky. The container has its own network namespace, so localhost inside the container is not the same as localhost on your host.
I run OpenClaw in Docker on both Azure VMs and home lab machines. Here is exactly how to get it working.
The Minimal Working docker-compose.yml
version: "3.8"
services:
openclaw:
image: openclaw/openclaw:latest
ports:
- "18789:18789"
environment:
- OPENCLAW_GATEWAY_BIND=0.0.0.0
- OPENCLAW_GATEWAY_CONTROLUI_ALLOWEDORIGINS=["http://YOUR_HOST_IP:18789"]
volumes:
- openclaw-data:/home/node/.openclaw
volumes:
openclaw-data:Replace YOUR_HOST_IP with your actual host machine IP address (not localhost, not 127.0.0.1).
Finding Your Host IP
# Linux
hostname -I | awk '{print $1}'
# macOS
ipconfig getifaddr en0
# Windows
ipconfig | findstr /i "IPv4"Why localhost Does Not Work
When you set allowedOrigins to http://localhost:18789, it only works if you open the browser on the same machine running Docker. From any other device, the browser sends a different Origin header (the host IP), which does not match.
Fix: Always use the actual IP address:
# Wrong
OPENCLAW_GATEWAY_CONTROLUI_ALLOWEDORIGINS=["http://localhost:18789"]
# Correct
OPENCLAW_GATEWAY_CONTROLUI_ALLOWEDORIGINS=["http://192.168.1.50:18789"]Docker Permission Denied Errors
If OpenClaw fails to start with permission errors:
Error: EACCES: permission denied, open '/home/node/.openclaw/openclaw.json'The container runs as user node (UID 1000). Fix the volume permissions:
# Named volume (usually works automatically)
docker compose down
docker volume rm openclaw-data
docker compose up -d
# Bind mount (manual fix needed)
sudo chown -R 1000:1000 ./openclaw-data
sudo chmod 700 ./openclaw-dataMultiple Access Methods
Allow access from both your local machine and your phone:
environment:
- OPENCLAW_GATEWAY_BIND=0.0.0.0
- OPENCLAW_GATEWAY_CONTROLUI_ALLOWEDORIGINS=["http://192.168.1.50:18789","http://localhost:18789"]Docker with Tailscale
If you use Tailscale on the host:
environment:
- OPENCLAW_GATEWAY_BIND=0.0.0.0
- OPENCLAW_GATEWAY_CONTROLUI_ALLOWEDORIGINS=["http://192.168.1.50:18789","http://my-machine.tail12345.ts.net:18789"]Docker with Reverse Proxy
When running behind Nginx or Traefik:
services:
openclaw:
image: openclaw/openclaw:latest
# No port mapping needed β proxy handles it
environment:
- OPENCLAW_GATEWAY_BIND=0.0.0.0
- OPENCLAW_GATEWAY_CONTROLUI_ALLOWEDORIGINS=["https://openclaw.yourdomain.com"]
networks:
- proxy
traefik:
# ... your proxy config
networks:
- proxy
networks:
proxy:
external: trueVerifying Configuration
After starting the container:
# Check if the gateway is running
docker compose logs openclaw | grep -i "gateway\|bind\|origin"
# Test from host
curl -I http://YOUR_HOST_IP:18789
# Check the stored config
docker compose exec openclaw cat /home/node/.openclaw/openclaw.jsonTroubleshooting Checklist
- Port mapped? Check
docker compose psshows0.0.0.0:18789->18789/tcp - Correct IP? The IP in
allowedOriginsmatches your browser address bar - Bind set?
OPENCLAW_GATEWAY_BIND=0.0.0.0(not loopback) - Volume permissions? UID 1000 owns the data directory
- Firewall? Port 18789 is open:
sudo ufw allow 18789/tcp