From 9767a96fede4a78435c105e5070e043c7c01cd91 Mon Sep 17 00:00:00 2001 From: fredrickchew Date: Tue, 21 Apr 2026 05:37:30 +0000 Subject: [PATCH 1/4] Update Dockerfile and add desktop entries for OpenClaw and ModelRelay --- docker/Dockerfile | 17 ++++++++++++----- docker/ModelRelay.desktop | 8 ++++++++ docker/OpenClaw.desktop | 8 ++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 docker/ModelRelay.desktop create mode 100644 docker/OpenClaw.desktop diff --git a/docker/Dockerfile b/docker/Dockerfile index b6d55d7..1a7c761 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ -ARG OPENCLAW_VERSION=2026.4.11 -ARG OLLAMA_VERSION=0.20.4 +ARG OPENCLAW_VERSION=2026.4.15 +ARG OLLAMA_VERSION=0.21.0 ARG NODE_VERSION=24 # Use the official Ollama image to get the binary @@ -19,7 +19,16 @@ RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm # Copy the Ollama binary from the official image COPY --from=ollama-bin --chown=abc:abc /usr/bin/ollama /usr/local/bin/ollama -RUN npm install -g openclaw@${OPENCLAW_VERSION} +RUN npm install -g openclaw@${OPENCLAW_VERSION} && \ + chown -R abc:abc /usr/local/lib/node_modules/openclaw /usr/local/bin/openclaw +COPY --chown=abc:abc OpenClaw.desktop /custom-cont-init.d/OpenClaw.desktop +# COPY --chown=abc:abc start-2-modelrelay.sh /custom-cont-init.d/start-2-modelrelay.sh + +# Install ModelRelay and start automatically when desktop loads +RUN npm install -g modelrelay@${MODELRELAY_VERSION} && \ + chown -R abc:abc /usr/local/lib/node_modules/modelrelay /usr/local/bin/modelrelay +COPY --chown=abc:abc ModelRelay.desktop /custom-cont-init.d/ModelRelay.desktop +# COPY --chown=abc:abc start-2-modelrelay.sh /custom-cont-init.d/start-2-modelrelay.sh # Start Ollama to start automatically when the desktop loads, RUN mkdir -p /custom-cont-init.d @@ -30,5 +39,3 @@ RUN echo "rm -rf /config/.npm" >> /custom-cont-init.d/init-openclaw.sh && \ echo "chown abc:abc -R /usr/local/bin &" >> /custom-cont-init.d/init-openclaw.sh && \ chmod +x /custom-cont-init.d/init-openclaw.sh -EXPOSE 11434 - diff --git a/docker/ModelRelay.desktop b/docker/ModelRelay.desktop new file mode 100644 index 0000000..a88a978 --- /dev/null +++ b/docker/ModelRelay.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Terminal=false +Exec=mate-terminal --title="ModelRelay" -e "bash -c 'modelrelay; exec bash'" +Name[en_US]=ModelRelay +Name=ModelRelay +GenericName[en_US.UTF-8]=ModelRelay \ No newline at end of file diff --git a/docker/OpenClaw.desktop b/docker/OpenClaw.desktop new file mode 100644 index 0000000..7bdb114 --- /dev/null +++ b/docker/OpenClaw.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Terminal=false +Exec=mate-terminal --title="OpenClaw" -e "bash -c 'openclaw gateway --port 18789 --allow-unconfigured --verbose; exec bash'" +Name[en_US]=OpenClaw +Name=PicoClaw +GenericName[en_US.UTF-8]=OpenClaw Gateway \ No newline at end of file From a99425cdc6a11f85b25ebd574f182335ddc894c8 Mon Sep 17 00:00:00 2001 From: fredrickchew Date: Tue, 21 Apr 2026 06:32:19 +0000 Subject: [PATCH 2/4] dev --- docker/common.sh | 57 +++++++++++++++++++++++++++++++++++++++ docker/init-modelrelay.sh | 53 ++++++++++++++++++++++++++++++++++++ docker/init-openclaw.sh | 7 +++++ 3 files changed, 117 insertions(+) create mode 100644 docker/common.sh create mode 100644 docker/init-modelrelay.sh create mode 100644 docker/init-openclaw.sh diff --git a/docker/common.sh b/docker/common.sh new file mode 100644 index 0000000..21676b9 --- /dev/null +++ b/docker/common.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Function to safely sync a desktop file if it has changed +# Usage: sync_desktop_file +sync_desktop_file() { + local SRC="$1" + local DEST="$2" + local DEST_DIR + local DEST_BASE + local TMP_DEST + + if [ ! -r "$SRC" ]; then + echo "Error: source file $SRC is missing or not readable." >&2 + return 1 + fi + + DEST_DIR="$(dirname "$DEST")" + DEST_BASE="$(basename "$DEST")" + + # Ensure directory exists and has correct ownership + mkdir -p "$DEST_DIR" + chown abc:abc "$DEST_DIR" + + TMP_DEST="$(mktemp "${DEST_DIR}/.${DEST_BASE}.tmp.XXXXXX")" || return 1 + + if [ -f "$DEST" ]; then + # Check if the file content is different + if ! cmp -s "$SRC" "$DEST"; then + echo "Updating $DEST (content changed). Preparing replacement" + if ! cp "$SRC" "$TMP_DEST"; then + rm -f "$TMP_DEST" + return 1 + fi + if ! chown abc:abc "$TMP_DEST"; then + rm -f "$TMP_DEST" + return 1 + fi + # Use a backup just in case, but overwrite it next time + mv "$DEST" "${DEST}.bak" 2>/dev/null || true + mv "$TMP_DEST" "$DEST" + else + echo "$DEST is already up to date." + rm -f "$TMP_DEST" + fi + else + echo "Creating $DEST" + if ! cp "$SRC" "$TMP_DEST"; then + rm -f "$TMP_DEST" + return 1 + fi + if ! chown abc:abc "$TMP_DEST"; then + rm -f "$TMP_DEST" + return 1 + fi + mv "$TMP_DEST" "$DEST" + fi +} \ No newline at end of file diff --git a/docker/init-modelrelay.sh b/docker/init-modelrelay.sh new file mode 100644 index 0000000..43a573e --- /dev/null +++ b/docker/init-modelrelay.sh @@ -0,0 +1,53 @@ +#!/bin/bash +source /custom-cont-init.d/common.sh || exit 1 + +SRC="/custom-cont-init.d/ModelRelay.desktop" + +add_model_if_missing() { + local file="$1" + + if ! jq -e '.models.providers | has("modelrelay")' "$file" > /dev/null; then + echo "[init-modelrelay] Adding modelrelay model to $file" + jq '.models.providers += { + modelrelay: { + "baseUrl": "http://127.0.0.1:7352/v1", + "api": "openai-completions", + "apiKey": "no-key", + "models": [ + { + "id": "auto-fastest", + "name": "Auto Fastest" + } + ] + }' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" + fi + + # Set modelrelay as default for agents if no default model is set + if jq -e '.agents.defaults.model.primary | select(. == null or . == "")' "$file" > /dev/null; then + echo "[init-modelrelay] Setting modelrelay as defaults for agents in $file" + jq '.agents |= (. // {}) | .agents.defaults |= (. // {}) | .agents.defaults.model |= (. // {}) | .agents.defaults.model.primary = "modelrelay/auto-fastest" | .agents.defaults.models |= (. // {}) | .agents.defaults.models["modelrelay/auto-fastest"] = {}' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" + fi + +} + +# Prep nodejs npm for ModelRelay +rm -rf /config/.npm +chown abc:abc -R /usr/local/lib/node_modules & +chown abc:abc -R /usr/local/bin & + +# Sync desktop file for autostart and desktop icon +sync_desktop_file "$SRC" "/config/.config/autostart/ModelRelay.desktop" +sync_desktop_file "$SRC" "/config/Desktop/ModelRelay.desktop" + +# Add modelrelay model to openclaw's config as soon as it appears, and set it as default for agents if no default was set +# /config/.openclaw/config.json +( + for i in {0..120}; do + if [ -f "/config/.openclaw/config.json" ]; then + add_model_if_missing "/config/.openclaw/config.json" + chown abc:abc "/config/.openclaw/config.json" + break + fi + sleep 5 + done +) & \ No newline at end of file diff --git a/docker/init-openclaw.sh b/docker/init-openclaw.sh new file mode 100644 index 0000000..be59fec --- /dev/null +++ b/docker/init-openclaw.sh @@ -0,0 +1,7 @@ +#!/bin/bash +source /custom-cont-init.d/common.sh || exit 1 + +SRC="/custom-cont-init.d/OpenClaw.desktop" + +sync_desktop_file "$SRC" "/config/.config/autostart/OpenClaw.desktop" +sync_desktop_file "$SRC" "/config/Desktop/OpenClaw.desktop" \ No newline at end of file From 7c5d9414e1e1e5914f57a5f7f1c5bad908d91490 Mon Sep 17 00:00:00 2001 From: fredrickchew Date: Tue, 21 Apr 2026 17:51:39 +0000 Subject: [PATCH 3/4] Refactor Dockerfile and initialization scripts for OpenClaw and ModelRelay --- docker/Dockerfile | 10 +++--- docker/common.sh | 0 docker/init-modelrelay.sh | 68 ++++++++++++++++++++++----------------- docker/init-openclaw.sh | 0 4 files changed, 43 insertions(+), 35 deletions(-) mode change 100644 => 100755 docker/common.sh mode change 100644 => 100755 docker/init-modelrelay.sh mode change 100644 => 100755 docker/init-openclaw.sh diff --git a/docker/Dockerfile b/docker/Dockerfile index 1a7c761..a1c5826 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -22,20 +22,18 @@ COPY --from=ollama-bin --chown=abc:abc /usr/bin/ollama /usr/local/bin/ollama RUN npm install -g openclaw@${OPENCLAW_VERSION} && \ chown -R abc:abc /usr/local/lib/node_modules/openclaw /usr/local/bin/openclaw COPY --chown=abc:abc OpenClaw.desktop /custom-cont-init.d/OpenClaw.desktop -# COPY --chown=abc:abc start-2-modelrelay.sh /custom-cont-init.d/start-2-modelrelay.sh +COPY --chown=abc:abc init-openclaw.sh /custom-cont-init.d/init-openclaw.sh # Install ModelRelay and start automatically when desktop loads RUN npm install -g modelrelay@${MODELRELAY_VERSION} && \ chown -R abc:abc /usr/local/lib/node_modules/modelrelay /usr/local/bin/modelrelay COPY --chown=abc:abc ModelRelay.desktop /custom-cont-init.d/ModelRelay.desktop -# COPY --chown=abc:abc start-2-modelrelay.sh /custom-cont-init.d/start-2-modelrelay.sh +COPY --chown=abc:abc init-modelrelay.sh /custom-cont-init.d/init-modelrelay.sh +COPY --chown=abc:abc common.sh /custom-cont-init.d/common.sh # Start Ollama to start automatically when the desktop loads, RUN mkdir -p /custom-cont-init.d RUN echo "runuser -l abc -c 'ollama serve &'" > /custom-cont-init.d/start-ollama.sh && \ chmod +x /custom-cont-init.d/start-ollama.sh -RUN echo "rm -rf /config/.npm" >> /custom-cont-init.d/init-openclaw.sh && \ - echo "chown abc:abc -R /usr/local/lib/node_modules &" >> /custom-cont-init.d/init-openclaw.sh && \ - echo "chown abc:abc -R /usr/local/bin &" >> /custom-cont-init.d/init-openclaw.sh && \ - chmod +x /custom-cont-init.d/init-openclaw.sh +COPY --chown=abc:abc init-openclaw.sh /custom-cont-init.d/init-openclaw.sh diff --git a/docker/common.sh b/docker/common.sh old mode 100644 new mode 100755 diff --git a/docker/init-modelrelay.sh b/docker/init-modelrelay.sh old mode 100644 new mode 100755 index 43a573e..fce684f --- a/docker/init-modelrelay.sh +++ b/docker/init-modelrelay.sh @@ -3,31 +3,40 @@ source /custom-cont-init.d/common.sh || exit 1 SRC="/custom-cont-init.d/ModelRelay.desktop" -add_model_if_missing() { - local file="$1" - - if ! jq -e '.models.providers | has("modelrelay")' "$file" > /dev/null; then - echo "[init-modelrelay] Adding modelrelay model to $file" - jq '.models.providers += { - modelrelay: { - "baseUrl": "http://127.0.0.1:7352/v1", - "api": "openai-completions", - "apiKey": "no-key", - "models": [ - { - "id": "auto-fastest", - "name": "Auto Fastest" - } - ] - }' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" - fi - - # Set modelrelay as default for agents if no default model is set - if jq -e '.agents.defaults.model.primary | select(. == null or . == "")' "$file" > /dev/null; then - echo "[init-modelrelay] Setting modelrelay as defaults for agents in $file" - jq '.agents |= (. // {}) | .agents.defaults |= (. // {}) | .agents.defaults.model |= (. // {}) | .agents.defaults.model.primary = "modelrelay/auto-fastest" | .agents.defaults.models |= (. // {}) | .agents.defaults.models["modelrelay/auto-fastest"] = {}' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" - fi - +configure_open_claw() { + local config_path="$1" + echo "[init-modelrelay] Configuring OpenClaw at $config_path" + + tmp_file=$(mktemp) + jq \ + --arg baseUrl "http://127.0.0.1:7352/v1" \ + ' + # Ensure base paths exist + .models //= {} | + .models.providers //= {} | + .agents //= {} | + .agents.defaults //= {} | + .agents.defaults.model //= {} | + .agents.defaults.models //= {} | + .agents.defaults.models["modelrelay/auto-fastest"] //= {} | + + # Logic for config.models.providers.modelrelay + .models.providers.modelrelay = { + "baseUrl": $baseUrl, + "api": "openai-completions", + "apiKey": "no-key", + "models": [ + { "id": "auto-fastest", "name": "Auto Fastest" } + ] + } | + + # Logic for config.agents.defaults.model.primary + .agents.defaults.model.primary = "modelrelay/auto-fastest" + + ' "$config_path" > "$tmp_file" && mv "$tmp_file" "$config_path" + cat "$config_path" + echo "Success: Configured $config_path" + return 0 } # Prep nodejs npm for ModelRelay @@ -40,12 +49,13 @@ sync_desktop_file "$SRC" "/config/.config/autostart/ModelRelay.desktop" sync_desktop_file "$SRC" "/config/Desktop/ModelRelay.desktop" # Add modelrelay model to openclaw's config as soon as it appears, and set it as default for agents if no default was set -# /config/.openclaw/config.json +# /config/.openclaw/openclaw.json ( for i in {0..120}; do - if [ -f "/config/.openclaw/config.json" ]; then - add_model_if_missing "/config/.openclaw/config.json" - chown abc:abc "/config/.openclaw/config.json" + echo "[init-modelrelay] i am here" + if [ -f "/config/.openclaw/openclaw.json.bak" ] && [ -f "/config/.openclaw/openclaw.json" ]; then + configure_open_claw "/config/.openclaw/openclaw.json" + chown abc:abc "/config/.openclaw/openclaw.json" break fi sleep 5 diff --git a/docker/init-openclaw.sh b/docker/init-openclaw.sh old mode 100644 new mode 100755 From d91b7fff6df0b9eaa115649e5aa9a70927c7f312 Mon Sep 17 00:00:00 2001 From: fredrickchew Date: Wed, 22 Apr 2026 06:18:01 +0000 Subject: [PATCH 4/4] Remove commented output and improve waiting message in init-modelrelay script --- docker/init-modelrelay.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/init-modelrelay.sh b/docker/init-modelrelay.sh index fce684f..e0ac8d9 100755 --- a/docker/init-modelrelay.sh +++ b/docker/init-modelrelay.sh @@ -34,7 +34,7 @@ configure_open_claw() { .agents.defaults.model.primary = "modelrelay/auto-fastest" ' "$config_path" > "$tmp_file" && mv "$tmp_file" "$config_path" - cat "$config_path" + # cat "$config_path" echo "Success: Configured $config_path" return 0 } @@ -52,7 +52,7 @@ sync_desktop_file "$SRC" "/config/Desktop/ModelRelay.desktop" # /config/.openclaw/openclaw.json ( for i in {0..120}; do - echo "[init-modelrelay] i am here" + echo "[init-modelrelay] Waiting to configure OpenClaw..." if [ -f "/config/.openclaw/openclaw.json.bak" ] && [ -f "/config/.openclaw/openclaw.json" ]; then configure_open_claw "/config/.openclaw/openclaw.json" chown abc:abc "/config/.openclaw/openclaw.json"