
This post will walk you through how to set up Openclaw in Docker with Azure Foundry and the Responses API.
Azure AI Foundry allows you to play around with many different models, but keep in mind you cannot set hard spend limits, so be sure to create a budget alert at the very least.
The responses API is important because then we can set things like reasoning effort.
Docker Network
If you want, create a docker network (bridge mode) just to contain your Openclaw. This is useful if you are running other containers on the same host just to isolate things a bit.
Docker Compose
Here is my docker compose:
services:
openclaw-gateway:
image: ${OPENCLAW_IMAGE:-ghcr.io/openclaw/openclaw:latest}
env_file:
- .env
networks:
- openclaw_network
environment:
HOME: /home/node
OPENCLAW_HOME: /home/node
TERM: xterm-256color
OPENCLAW_STATE_DIR: /home/node/.openclaw
OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
OPENCLAW_CONFIG_DIR: /home/node/.openclaw
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
volumes:
- ./data:/home/node/.openclaw
- ./workspace:/home/node/.openclaw/workspace
- ./secrets:/home/node/.config/openclaw
# Uncomment if running Docker-in-Docker sandboxing:
# - /var/run/docker.sock:/var/run/docker.sock
cap_drop:
- NET_RAW
- NET_ADMIN
security_opt:
- no-new-privileges:true
extra_hosts:
- "host.docker.internal:host-gateway"
ports:
- "${OPENCLAW_GATEWAY_PORT:-18789}:18789"
- "${OPENCLAW_BRIDGE_PORT:-18790}:18790"
- "${OPENCLAW_MSTEAMS_PORT:-3978}:3978"
init: true
restart: unless-stopped
command:
[
"node",
"dist/index.js",
"gateway",
"--bind",
"${OPENCLAW_GATEWAY_BIND:-lan}",
"--port",
"18789",
]
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://127.0.0.1:18789/healthz').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))",
]
interval: 30s
timeout: 5s
retries: 5
start_period: 20s
openclaw-cli:
image: ${OPENCLAW_IMAGE:-ghcr.io/openclaw/openclaw:latest}
network_mode: "service:openclaw-gateway"
env_file:
- .env
# Not needed because network_mode is defined, which piggybacks this container on the gw container
#networks:
# - openclaw_network
cap_drop:
- NET_RAW
- NET_ADMIN
security_opt:
- no-new-privileges:true
environment:
HOME: /home/node
OPENCLAW_HOME: /home/node
TERM: xterm-256color
OPENCLAW_STATE_DIR: /home/node/.openclaw
OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
OPENCLAW_CONFIG_DIR: /home/node/.openclaw
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
BROWSER: echo
volumes:
- ./data:/home/node/.openclaw
- ./workspace:/home/node/.openclaw/workspace
- ./secrets:/home/node/.config/openclaw
stdin_open: true
tty: true
init: true
entrypoint: ["node", "dist/index.js"]
depends_on:
- openclaw-gateway
networks:
openclaw_network:
external: true
Docker env File
# Image & Ports
OPENCLAW_IMAGE=ghcr.io/openclaw/openclaw:latest
OPENCLAW_GATEWAY_PORT=18789
OPENCLAW_BRIDGE_PORT=18790
OPENCLAW_MSTEAMS_PORT=3978
OPENCLAW_GATEWAY_BIND=lan
OPENCLAW_TZ=Africa/Johannesburg
# Gateway Security & Tokens
OPENCLAW_GATEWAY_TOKEN=xxx
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=
OPENCLAW_DISABLE_BONJOUR=1
# -----------------------------------------------------------------------------
# LLM Provider API Keys
# -----------------------------------------------------------------------------
MICROSOFT_FOUNDRY_API_KEY=xxx
OPENAI_API_KEY=sk-proj-xxx
GEMINI_API_KEY=xxx
# OpenTelemetry Monitoring (Optional)
OTEL_EXPORTER_OTLP_ENDPOINT=
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_SERVICE_NAME=openclaw
OTEL_SEMCONV_STABILITY_OPT_IN=
OPENCLAW_OTEL_PRELOADED=
Start the Stack (compose up)
You will most likely get an “EACCES” error. To fix it, do this:
Be in your Openclaw directory where it creates the data, workspace, and secrets folder. Here is mine:

# 1. Stop the stack first
docker compose down
Then cd into the directory where the folders are that the openclaw container created
# 2. Grant ownership of your local mount folders to UID 1000 (container's node user)
sudo chown -R 1000:1000 ./data ./workspace ./secrets
# 3. Ensure read/write/execute permissions are set for the owner
chmod -R 755 ./data ./workspace ./secrets
# 4. Bring the stack back up
docker compose up -d
Then you need to create a minimal config file, otherwhise your Openclaw will throw this error: Missing config. Run openclaw setup or set gateway.mode=local (or pass –allow-unconfigured).
Create this in ./data/openclaw.json
{
"gateway": {
"mode": "local",
"bind": "lan",
"port": 18789,
"trustedProxies": [
"172.21.0.0/16"
],
"controlUi": {
"allowedOrigins": [
"https://openclaw.internal.leighonline.net"
]
}
},
"agents": {
"defaults": {
"model": {
"primary": "microsoft-foundry/gpt-5.6-xxx-xxx",
"fallbacks": [
"openai/gpt-5.6-luna",
"google/gemini-flash-latest"
]
}
}
},
"plugins": {
"entries": {
"canvas": {
"enabled": true,
"config": {
"host": {
"root": "~/.openclaw/workspace/canvas"
}
}
}
}
},
"meta": {
"lastTouchedVersion": "2026.7.1",
"lastTouchedAt": "2026-08-02T05:55:49.213Z"
},
"models": {
"pricing": {
"enabled": true
},
"providers": {
"microsoft-foundry": {
"baseUrl": "https://<foundry-url>.services.ai.azure.com/openai/v1",
"apiKey": "${MICROSOFT_FOUNDRY_API_KEY}",
"api": "openai-responses",
"authHeader": false,
"headers": {
"api-key": "${MICROSOFT_FOUNDRY_API_KEY}"
}
}
}
}
}
Then change permissions “sudo chown 1000:1000 ./data/openclaw.json“
What the Proxies and AllowedOrigin config does
- TrustedProxies section: This is your openclaw docker network range. Add it in there so that Openclaw knows this is you when connecting from your web browser.
- AllowedOrigins section: This is needed if you want to access Openclaw via HTTPS later on. We need to add this for its CORS to allow our custom domain.
Fix permissions of the file just in case “sudo chown 1000:1000 ./data/openclaw.json“
Openclaw HTTPS
To access Openclaw over HTTPS I will just be using my existing NGINX Proxy manager and attach it to my Openclaw network
services:
nginxproxymanager:
container_name: nginxproxymanager
networks:
- internal_proxy
- openclaw_network
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
#- '80:80' # Public HTTP Port. Not needed because NPM has an entry for iteself mapped to port 81
- '443:443' # Public HTTPS Port
- '81'
#- '81:81' # Admin Web Port. Not needed because NPM has an entry for iteself mapped to port 81
environment:
DISABLE_IPV6: 'true'
volumes:
- /opt/stacks/stacks/Proxmox-Production/nginxproxymanager/database:/data
- /opt/stacks/stacks/Proxmox-Production/nginxproxymanager/certs:/etc/letsencrypt
#- /opt/nginxproxymanager:/data
#- /opt/nginxproxymanager:/etc/letsencrypt
networks:
internal_proxy:
external: true
openclaw_network:
external: true
Be sure to enable websocket support.

Openclaw HTTPS
If all goes well, you will see this page. Just paste the token (the 32 character hex) you had in your env file

You will need to connect to the openclaw-cli container and approve your browser. Note that approval token.

Connect to your openclaw-cli container and run this:
docker exec -it openclaw-openclaw-cli-1 node dist/index.js devices approve 8cdxxxxxxxxxxx
Then just refresh your page and then you are in!