gateway configs
This commit is contained in:
18
AGENTS.md
18
AGENTS.md
@@ -418,6 +418,24 @@ docker exec CONTAINER_NAME sh -c 'echo {} > /home/node/.openclaw/devices/pending
|
|||||||
- Localhost (`127.0.0.1`) auto-approves.
|
- Localhost (`127.0.0.1`) auto-approves.
|
||||||
- Config edits trigger Gateway reload/restart automatically; container restart is usually unnecessary.
|
- Config edits trigger Gateway reload/restart automatically; container restart is usually unnecessary.
|
||||||
|
|
||||||
|
### Keep Web UI Working Across Rebuilds
|
||||||
|
|
||||||
|
To avoid repeated reconnect/pairing friction after redeploys:
|
||||||
|
|
||||||
|
1. Keep a stable Tailscale hostname so the browser origin does not change:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
TAILSCALE_HOSTNAME=openclaw-gateway
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Keep the same `OPENCLAW_GATEWAY_TOKEN` between deployments.
|
||||||
|
3. Persist and reuse the same `openclaw-config` volume (contains `devices/paired.json`).
|
||||||
|
4. If UI shows `token_missing`, open a tokenized URL and re-save settings:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec CONTAINER_NAME node dist/index.js dashboard --no-open
|
||||||
|
```
|
||||||
|
|
||||||
### Permission Denied Errors
|
### Permission Denied Errors
|
||||||
|
|
||||||
**Problem**: `EACCES: permission denied, open '/home/node/.openclaw/workspace/...'`
|
**Problem**: `EACCES: permission denied, open '/home/node/.openclaw/workspace/...'`
|
||||||
|
|||||||
@@ -32,8 +32,13 @@ services:
|
|||||||
TERM: xterm-256color
|
TERM: xterm-256color
|
||||||
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
|
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
|
||||||
MOONSHOT_API_KEY: ${MOONSHOT_API_KEY}
|
MOONSHOT_API_KEY: ${MOONSHOT_API_KEY}
|
||||||
|
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||||
|
OPENCLAW_GATEWAY_BIND: ${OPENCLAW_GATEWAY_BIND:-lan}
|
||||||
|
OPENCLAW_TAILSCALE_MODE: ${OPENCLAW_TAILSCALE_MODE:-off}
|
||||||
|
OPENCLAW_ENABLE_TAILSCALE: ${OPENCLAW_ENABLE_TAILSCALE:-0}
|
||||||
GOG_ACCOUNT: ${GOG_ACCOUNT:-}
|
GOG_ACCOUNT: ${GOG_ACCOUNT:-}
|
||||||
TAILSCALE_AUTH_KEY: ${TAILSCALE_AUTH_KEY:-}
|
TAILSCALE_AUTH_KEY: ${TAILSCALE_AUTH_KEY:-}
|
||||||
|
TAILSCALE_HOSTNAME: ${TAILSCALE_HOSTNAME:-openclaw-gateway}
|
||||||
volumes:
|
volumes:
|
||||||
- openclaw-config:/home/node/.openclaw
|
- openclaw-config:/home/node/.openclaw
|
||||||
- openclaw-workspace:/home/node/.openclaw/workspace
|
- openclaw-workspace:/home/node/.openclaw/workspace
|
||||||
@@ -44,12 +49,7 @@ services:
|
|||||||
init: true
|
init: true
|
||||||
networks:
|
networks:
|
||||||
- dokploy-network
|
- dokploy-network
|
||||||
command:
|
command: ["/usr/local/bin/start-gateway.sh"]
|
||||||
[
|
|
||||||
"/bin/sh",
|
|
||||||
"-c",
|
|
||||||
"/home/node/.local/bin/tailscale-start.sh && node dist/index.js gateway --port 18789",
|
|
||||||
]
|
|
||||||
# healthcheck:
|
# healthcheck:
|
||||||
# test: ["CMD", "healthcheck.sh"]
|
# test: ["CMD", "healthcheck.sh"]
|
||||||
# interval: 30s
|
# interval: 30s
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ RUN echo '#!/bin/sh' > /home/node/.local/bin/tailscale-start.sh && \
|
|||||||
echo 'mkdir -p /var/run/tailscale /home/node/.local/share/tailscale /home/node/.local/share/tailscale/files' >> /home/node/.local/bin/tailscale-start.sh && \
|
echo 'mkdir -p /var/run/tailscale /home/node/.local/share/tailscale /home/node/.local/share/tailscale/files' >> /home/node/.local/bin/tailscale-start.sh && \
|
||||||
echo 'tailscaled --socket=/tmp/tailscale.sock --tun=userspace-networking &' >> /home/node/.local/bin/tailscale-start.sh && \
|
echo 'tailscaled --socket=/tmp/tailscale.sock --tun=userspace-networking &' >> /home/node/.local/bin/tailscale-start.sh && \
|
||||||
echo 'sleep 3' >> /home/node/.local/bin/tailscale-start.sh && \
|
echo 'sleep 3' >> /home/node/.local/bin/tailscale-start.sh && \
|
||||||
echo 'tailscale --socket=/tmp/tailscale.sock up --authkey=$TAILSCALE_AUTH_KEY' >> /home/node/.local/bin/tailscale-start.sh && \
|
echo 'if [ -n "$TAILSCALE_AUTH_KEY" ]; then tailscale --socket=/tmp/tailscale.sock up --authkey="$TAILSCALE_AUTH_KEY" --hostname="${TAILSCALE_HOSTNAME:-openclaw-gateway}" || true; fi' >> /home/node/.local/bin/tailscale-start.sh && \
|
||||||
echo 'sleep 2' >> /home/node/.local/bin/tailscale-start.sh && \
|
echo 'sleep 2' >> /home/node/.local/bin/tailscale-start.sh && \
|
||||||
echo 'tailscale --socket=/tmp/tailscale.sock serve --bg 18789' >> /home/node/.local/bin/tailscale-start.sh && \
|
echo 'tailscale --socket=/tmp/tailscale.sock serve --bg 18789 || true' >> /home/node/.local/bin/tailscale-start.sh && \
|
||||||
chmod +x /home/node/.local/bin/tailscale-start.sh
|
chmod +x /home/node/.local/bin/tailscale-start.sh
|
||||||
|
|
||||||
# Copy custom tools into the image
|
# Copy custom tools into the image
|
||||||
@@ -54,7 +54,7 @@ COPY bin/* /usr/local/bin/
|
|||||||
RUN chmod +x /usr/local/bin/*
|
RUN chmod +x /usr/local/bin/*
|
||||||
|
|
||||||
# Create directories in the persistent volume location
|
# Create directories in the persistent volume location
|
||||||
RUN mkdir -p /home/node/.openclaw/ssh /home/node/.openclaw/gog \
|
RUN mkdir -p /home/node/.openclaw/ssh /home/node/.openclaw/gog /opt/openclaw/defaults \
|
||||||
&& chown -R node:node /home/node/.openclaw
|
&& chown -R node:node /home/node/.openclaw
|
||||||
|
|
||||||
# Link gog config and ssh to standard locations
|
# Link gog config and ssh to standard locations
|
||||||
@@ -62,8 +62,9 @@ RUN mkdir -p /home/node/.config /home/node/.ssh \
|
|||||||
&& ln -sf /home/node/.openclaw/gog /home/node/.config/gog \
|
&& ln -sf /home/node/.openclaw/gog /home/node/.config/gog \
|
||||||
&& ln -sf /home/node/.openclaw/ssh /home/node/.ssh
|
&& ln -sf /home/node/.openclaw/ssh /home/node/.ssh
|
||||||
|
|
||||||
# Copy config into the image
|
# Copy default config into the image
|
||||||
COPY config/openclaw.json /home/node/.openclaw/openclaw.json
|
COPY config/openclaw.json /opt/openclaw/defaults/openclaw.json
|
||||||
|
RUN chown -R node:node /opt/openclaw/defaults
|
||||||
|
|
||||||
# Switch back to node user
|
# Switch back to node user
|
||||||
USER node
|
USER node
|
||||||
|
|||||||
69
docker/bin/start-gateway.sh
Normal file
69
docker/bin/start-gateway.sh
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
CONFIG_DIR="${HOME:-/home/node}/.openclaw"
|
||||||
|
CONFIG_FILE="${CONFIG_DIR}/openclaw.json"
|
||||||
|
DEFAULT_CONFIG="/opt/openclaw/defaults/openclaw.json"
|
||||||
|
BIND="${OPENCLAW_GATEWAY_BIND:-lan}"
|
||||||
|
TAILSCALE_MODE="${OPENCLAW_TAILSCALE_MODE:-off}"
|
||||||
|
PORT="${OPENCLAW_GATEWAY_PORT:-18789}"
|
||||||
|
|
||||||
|
mkdir -p "${CONFIG_DIR}"
|
||||||
|
|
||||||
|
if [ ! -f "${CONFIG_FILE}" ] && [ -f "${DEFAULT_CONFIG}" ]; then
|
||||||
|
cp "${DEFAULT_CONFIG}" "${CONFIG_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${CONFIG_FILE}" ]; then
|
||||||
|
printf '{}\n' > "${CONFIG_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp_file="$(mktemp)"
|
||||||
|
jq \
|
||||||
|
--arg bind "${BIND}" \
|
||||||
|
--arg tailscale_mode "${TAILSCALE_MODE}" \
|
||||||
|
--arg token "${OPENCLAW_GATEWAY_TOKEN:-}" \
|
||||||
|
'
|
||||||
|
.env.OPENCLAW_GATEWAY_TOKEN = "${OPENCLAW_GATEWAY_TOKEN}" |
|
||||||
|
.env.OPENAI_API_KEY = "${OPENAI_API_KEY}" |
|
||||||
|
.gateway.bind = $bind |
|
||||||
|
.gateway.tailscale.mode = $tailscale_mode |
|
||||||
|
.gateway.auth.mode = "token" |
|
||||||
|
.gateway.auth.token = (if $token == "" then (.gateway.auth.token // "${OPENCLAW_GATEWAY_TOKEN}") else $token end) |
|
||||||
|
.gateway.controlUi.allowInsecureAuth = true |
|
||||||
|
.models.providers.openai = {
|
||||||
|
baseUrl: "https://api.openai.com/v1",
|
||||||
|
apiKey: "${OPENAI_API_KEY}",
|
||||||
|
auth: "api-key",
|
||||||
|
api: "openai-completions",
|
||||||
|
models: [
|
||||||
|
{
|
||||||
|
id: "gpt-4.1-mini",
|
||||||
|
name: "GPT-4.1 mini",
|
||||||
|
reasoning: false,
|
||||||
|
input: ["text"],
|
||||||
|
cost: {input: 0, output: 0, cacheRead: 0, cacheWrite: 0},
|
||||||
|
contextWindow: 1047576,
|
||||||
|
maxTokens: 32768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "gpt-image-1",
|
||||||
|
name: "GPT Image 1",
|
||||||
|
reasoning: false,
|
||||||
|
input: ["text", "image"],
|
||||||
|
cost: {input: 0, output: 0, cacheRead: 0, cacheWrite: 0},
|
||||||
|
contextWindow: 128000,
|
||||||
|
maxTokens: 4096
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} |
|
||||||
|
.agents.defaults.model.fallbacks = ((.agents.defaults.model.fallbacks // []) + ["openai/gpt-4.1-mini"] | unique) |
|
||||||
|
.agents.defaults.models["openai/gpt-4.1-mini"] = {alias: "OpenAI GPT-4.1 mini"}
|
||||||
|
' "${CONFIG_FILE}" > "${tmp_file}"
|
||||||
|
mv "${tmp_file}" "${CONFIG_FILE}"
|
||||||
|
|
||||||
|
if [ "${OPENCLAW_ENABLE_TAILSCALE:-0}" = "1" ] && [ -x /home/node/.local/bin/tailscale-start.sh ]; then
|
||||||
|
/home/node/.local/bin/tailscale-start.sh || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec node dist/index.js gateway --bind "${BIND}" --port "${PORT}"
|
||||||
@@ -5,7 +5,8 @@
|
|||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"MOONSHOT_API_KEY": "${MOONSHOT_API_KEY}",
|
"MOONSHOT_API_KEY": "${MOONSHOT_API_KEY}",
|
||||||
"OPENCLAW_GATEWAY_TOKEN": "${OPENCLAW_GATEWAY_TOKEN}"
|
"OPENCLAW_GATEWAY_TOKEN": "${OPENCLAW_GATEWAY_TOKEN}",
|
||||||
|
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
|
||||||
},
|
},
|
||||||
"wizard": {
|
"wizard": {
|
||||||
"lastRunAt": "2026-02-19T04:49:36.701Z",
|
"lastRunAt": "2026-02-19T04:49:36.701Z",
|
||||||
@@ -23,11 +24,47 @@
|
|||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
"providers": {
|
"providers": {
|
||||||
|
"openai": {
|
||||||
|
"baseUrl": "https://api.openai.com/v1",
|
||||||
|
"apiKey": "${OPENAI_API_KEY}",
|
||||||
|
"auth": "api-key",
|
||||||
|
"api": "openai-completions",
|
||||||
|
"models": [
|
||||||
|
{
|
||||||
|
"id": "gpt-4.1-mini",
|
||||||
|
"name": "GPT-4.1 mini",
|
||||||
|
"reasoning": false,
|
||||||
|
"input": ["text"],
|
||||||
|
"cost": {
|
||||||
|
"input": 0,
|
||||||
|
"output": 0,
|
||||||
|
"cacheRead": 0,
|
||||||
|
"cacheWrite": 0
|
||||||
|
},
|
||||||
|
"contextWindow": 1047576,
|
||||||
|
"maxTokens": 32768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "gpt-image-1",
|
||||||
|
"name": "GPT Image 1",
|
||||||
|
"reasoning": false,
|
||||||
|
"input": ["text", "image"],
|
||||||
|
"cost": {
|
||||||
|
"input": 0,
|
||||||
|
"output": 0,
|
||||||
|
"cacheRead": 0,
|
||||||
|
"cacheWrite": 0
|
||||||
|
},
|
||||||
|
"contextWindow": 128000,
|
||||||
|
"maxTokens": 4096
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"moonshot": {
|
"moonshot": {
|
||||||
"baseUrl": "https://api.moonshot.ai/v1",
|
"baseUrl": "https://api.moonshot.ai/v1",
|
||||||
"apiKey": "${MOONSHOT_API_KEY}",
|
"apiKey": "${MOONSHOT_API_KEY}",
|
||||||
"auth": "api-key",
|
"auth": "api-key",
|
||||||
"api": "openai-responses",
|
"api": "openai-completions",
|
||||||
"models": [
|
"models": [
|
||||||
{
|
{
|
||||||
"id": "kimi-k2.5",
|
"id": "kimi-k2.5",
|
||||||
@@ -51,13 +88,16 @@
|
|||||||
"defaults": {
|
"defaults": {
|
||||||
"model": {
|
"model": {
|
||||||
"primary": "kimi-coding/k2p5",
|
"primary": "kimi-coding/k2p5",
|
||||||
"fallbacks": ["moonshot/kimi-k2.5"]
|
"fallbacks": ["moonshot/kimi-k2.5", "openai/gpt-4.1-mini"]
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
"moonshot/kimi-k2.5": {
|
"kimi-coding/k2p5": {
|
||||||
"alias": "Kimi K2.5"
|
"alias": "Kimi K2.5"
|
||||||
},
|
},
|
||||||
"kimi-coding/k2p5": {
|
"openai/gpt-4.1-mini": {
|
||||||
|
"alias": "OpenAI GPT-4.1 mini"
|
||||||
|
},
|
||||||
|
"moonshot/kimi-k2.5": {
|
||||||
"alias": "Kimi K2.5"
|
"alias": "Kimi K2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -97,9 +137,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gateway": {
|
"gateway": {
|
||||||
"bind": "loopback",
|
"bind": "lan",
|
||||||
|
"auth": {
|
||||||
|
"mode": "token",
|
||||||
|
"token": "${OPENCLAW_GATEWAY_TOKEN}"
|
||||||
|
},
|
||||||
|
"controlUi": {
|
||||||
|
"allowInsecureAuth": true
|
||||||
|
},
|
||||||
"tailscale": {
|
"tailscale": {
|
||||||
"mode": "serve",
|
"mode": "off",
|
||||||
"resetOnExit": false
|
"resetOnExit": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
15
stack.yml
15
stack.yml
@@ -8,6 +8,10 @@ services:
|
|||||||
TERM: xterm-256color
|
TERM: xterm-256color
|
||||||
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
|
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
|
||||||
MOONSHOT_API_KEY: ${MOONSHOT_API_KEY}
|
MOONSHOT_API_KEY: ${MOONSHOT_API_KEY}
|
||||||
|
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||||
|
OPENCLAW_GATEWAY_BIND: ${OPENCLAW_GATEWAY_BIND:-lan}
|
||||||
|
OPENCLAW_TAILSCALE_MODE: ${OPENCLAW_TAILSCALE_MODE:-off}
|
||||||
|
OPENCLAW_ENABLE_TAILSCALE: ${OPENCLAW_ENABLE_TAILSCALE:-0}
|
||||||
GOG_ACCOUNT: ${GOG_ACCOUNT:-}
|
GOG_ACCOUNT: ${GOG_ACCOUNT:-}
|
||||||
volumes:
|
volumes:
|
||||||
- openclaw-config:/home/node/.openclaw
|
- openclaw-config:/home/node/.openclaw
|
||||||
@@ -29,16 +33,7 @@ services:
|
|||||||
- node.hostname == tpi-n1
|
- node.hostname == tpi-n1
|
||||||
networks:
|
networks:
|
||||||
- dokploy-network
|
- dokploy-network
|
||||||
command:
|
command: ["/usr/local/bin/start-gateway.sh"]
|
||||||
[
|
|
||||||
"node",
|
|
||||||
"dist/index.js",
|
|
||||||
"gateway",
|
|
||||||
"--bind",
|
|
||||||
"${OPENCLAW_GATEWAY_BIND:-lan}",
|
|
||||||
"--port",
|
|
||||||
"18789",
|
|
||||||
]
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
openclaw-config:
|
openclaw-config:
|
||||||
|
|||||||
Reference in New Issue
Block a user