mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-08 21:09:23 +08:00
fix(docker): support .mjs entrypoints in images and e2e
This commit is contained in:
@@ -44,5 +44,5 @@ USER node
|
||||
#
|
||||
# For container platforms requiring external health checks:
|
||||
# 1. Set OPENCLAW_GATEWAY_TOKEN or OPENCLAW_GATEWAY_PASSWORD env var
|
||||
# 2. Override CMD: ["node","dist/index.js","gateway","--allow-unconfigured","--bind","lan"]
|
||||
CMD ["node", "dist/index.js", "gateway", "--allow-unconfigured"]
|
||||
# 2. Override CMD: ["node","openclaw.mjs","gateway","--allow-unconfigured","--bind","lan"]
|
||||
CMD ["node", "openclaw.mjs", "gateway", "--allow-unconfigured"]
|
||||
|
||||
21
openclaw.mjs
21
openclaw.mjs
@@ -11,4 +11,23 @@ if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
||||
}
|
||||
}
|
||||
|
||||
await import("./dist/entry.js");
|
||||
const tryImport = async (specifier) => {
|
||||
try {
|
||||
await import(specifier);
|
||||
return true;
|
||||
} catch (err) {
|
||||
// Only swallow missing-module errors; rethrow real runtime errors.
|
||||
if (err && typeof err === "object" && "code" in err && err.code === "ERR_MODULE_NOT_FOUND") {
|
||||
return false;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
if (await tryImport("./dist/entry.js")) {
|
||||
// OK
|
||||
} else if (await tryImport("./dist/entry.mjs")) {
|
||||
// OK
|
||||
} else {
|
||||
throw new Error("openclaw: missing dist/entry.(m)js (build output).");
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ WORKDIR /app
|
||||
|
||||
ENV NODE_OPTIONS="--disable-warning=ExperimentalWarning"
|
||||
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json vitest.config.ts vitest.e2e.config.ts openclaw.mjs ./
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json tsdown.config.ts vitest.config.ts vitest.e2e.config.ts openclaw.mjs ./
|
||||
COPY src ./src
|
||||
COPY test ./test
|
||||
COPY scripts ./scripts
|
||||
|
||||
@@ -81,8 +81,18 @@ LOGINCTL
|
||||
npm install -g --prefix /tmp/npm-prefix "/app/$pkg_tgz"
|
||||
|
||||
npm_bin="/tmp/npm-prefix/bin/openclaw"
|
||||
npm_entry="/tmp/npm-prefix/lib/node_modules/openclaw/dist/index.js"
|
||||
npm_root="/tmp/npm-prefix/lib/node_modules/openclaw"
|
||||
if [ -f "$npm_root/dist/index.mjs" ]; then
|
||||
npm_entry="$npm_root/dist/index.mjs"
|
||||
else
|
||||
npm_entry="$npm_root/dist/index.js"
|
||||
fi
|
||||
|
||||
if [ -f "/app/dist/index.mjs" ]; then
|
||||
git_entry="/app/dist/index.mjs"
|
||||
else
|
||||
git_entry="/app/dist/index.js"
|
||||
fi
|
||||
git_cli="/app/openclaw.mjs"
|
||||
|
||||
assert_entrypoint() {
|
||||
|
||||
@@ -31,7 +31,7 @@ echo "Starting gateway container..."
|
||||
-e "OPENCLAW_SKIP_CRON=1" \
|
||||
-e "OPENCLAW_SKIP_CANVAS_HOST=1" \
|
||||
"$IMAGE_NAME" \
|
||||
bash -lc "node dist/index.js gateway --port $PORT --bind lan --allow-unconfigured > /tmp/gateway-net-e2e.log 2>&1"
|
||||
bash -lc "entry=dist/index.mjs; [ -f \"\$entry\" ] || entry=dist/index.js; node \"\$entry\" gateway --port $PORT --bind lan --allow-unconfigured > /tmp/gateway-net-e2e.log 2>&1"
|
||||
|
||||
echo "Waiting for gateway to come up..."
|
||||
ready=0
|
||||
@@ -77,9 +77,9 @@ docker run --rm \
|
||||
-e "GW_URL=ws://$GW_NAME:$PORT" \
|
||||
-e "GW_TOKEN=$TOKEN" \
|
||||
"$IMAGE_NAME" \
|
||||
bash -lc "node - <<'NODE'
|
||||
bash -lc "node --import tsx - <<'NODE'
|
||||
import { WebSocket } from \"ws\";
|
||||
import { PROTOCOL_VERSION } from \"./dist/gateway/protocol/index.js\";
|
||||
import { PROTOCOL_VERSION } from \"./src/gateway/protocol/index.ts\";
|
||||
|
||||
const url = process.env.GW_URL;
|
||||
const token = process.env.GW_TOKEN;
|
||||
|
||||
@@ -13,6 +13,17 @@ docker run --rm -t "$IMAGE_NAME" bash -lc '
|
||||
trap "" PIPE
|
||||
export TERM=xterm-256color
|
||||
ONBOARD_FLAGS="--flow quickstart --auth-choice skip --skip-channels --skip-skills --skip-daemon --skip-ui"
|
||||
# tsdown may emit dist/index.js or dist/index.mjs depending on runtime/bundler.
|
||||
if [ -f dist/index.mjs ]; then
|
||||
OPENCLAW_ENTRY="dist/index.mjs"
|
||||
elif [ -f dist/index.js ]; then
|
||||
OPENCLAW_ENTRY="dist/index.js"
|
||||
else
|
||||
echo "Missing dist/index.(m)js (build output):"
|
||||
ls -la dist || true
|
||||
exit 1
|
||||
fi
|
||||
export OPENCLAW_ENTRY
|
||||
|
||||
# Provide a minimal trash shim to avoid noisy "missing trash" logs in containers.
|
||||
export PATH="/tmp/openclaw-bin:$PATH"
|
||||
@@ -83,7 +94,7 @@ TRASH
|
||||
}
|
||||
|
||||
start_gateway() {
|
||||
node dist/index.js gateway --port 18789 --bind loopback --allow-unconfigured > /tmp/gateway-e2e.log 2>&1 &
|
||||
node "$OPENCLAW_ENTRY" gateway --port 18789 --bind loopback --allow-unconfigured > /tmp/gateway-e2e.log 2>&1 &
|
||||
GATEWAY_PID="$!"
|
||||
}
|
||||
|
||||
@@ -185,7 +196,7 @@ TRASH
|
||||
local validate_fn="${4:-}"
|
||||
|
||||
# Default onboarding command wrapper.
|
||||
run_wizard_cmd "$case_name" "$home_dir" "node dist/index.js onboard $ONBOARD_FLAGS" "$send_fn" true "$validate_fn"
|
||||
run_wizard_cmd "$case_name" "$home_dir" "node \"$OPENCLAW_ENTRY\" onboard $ONBOARD_FLAGS" "$send_fn" true "$validate_fn"
|
||||
}
|
||||
|
||||
make_home() {
|
||||
@@ -268,7 +279,7 @@ TRASH
|
||||
home_dir="$(make_home local-basic)"
|
||||
export HOME="$home_dir"
|
||||
mkdir -p "$HOME"
|
||||
node dist/index.js onboard \
|
||||
node "$OPENCLAW_ENTRY" onboard \
|
||||
--non-interactive \
|
||||
--accept-risk \
|
||||
--flow quickstart \
|
||||
@@ -345,7 +356,7 @@ NODE
|
||||
export HOME="$home_dir"
|
||||
mkdir -p "$HOME"
|
||||
# Smoke test non-interactive remote config write.
|
||||
node dist/index.js onboard --non-interactive --accept-risk \
|
||||
node "$OPENCLAW_ENTRY" onboard --non-interactive --accept-risk \
|
||||
--mode remote \
|
||||
--remote-url ws://gateway.local:18789 \
|
||||
--remote-token remote-token \
|
||||
@@ -398,7 +409,7 @@ NODE
|
||||
}
|
||||
JSON
|
||||
|
||||
node dist/index.js onboard \
|
||||
node "$OPENCLAW_ENTRY" onboard \
|
||||
--non-interactive \
|
||||
--accept-risk \
|
||||
--flow quickstart \
|
||||
@@ -441,7 +452,7 @@ NODE
|
||||
local home_dir
|
||||
home_dir="$(make_home channels)"
|
||||
# Channels-only configure flow.
|
||||
run_wizard_cmd channels "$home_dir" "node dist/index.js configure --section channels" send_channels_flow
|
||||
run_wizard_cmd channels "$home_dir" "node \"$OPENCLAW_ENTRY\" configure --section channels" send_channels_flow
|
||||
|
||||
config_path="$HOME/.openclaw/openclaw.json"
|
||||
assert_file "$config_path"
|
||||
@@ -492,7 +503,7 @@ NODE
|
||||
}
|
||||
JSON
|
||||
|
||||
run_wizard_cmd skills "$home_dir" "node dist/index.js configure --section skills" send_skills_flow
|
||||
run_wizard_cmd skills "$home_dir" "node \"$OPENCLAW_ENTRY\" configure --section skills" send_skills_flow
|
||||
|
||||
config_path="$HOME/.openclaw/openclaw.json"
|
||||
assert_file "$config_path"
|
||||
|
||||
@@ -10,6 +10,16 @@ docker build -t "$IMAGE_NAME" -f "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR"
|
||||
echo "Running plugins Docker E2E..."
|
||||
docker run --rm -t "$IMAGE_NAME" bash -lc '
|
||||
set -euo pipefail
|
||||
if [ -f dist/index.mjs ]; then
|
||||
OPENCLAW_ENTRY="dist/index.mjs"
|
||||
elif [ -f dist/index.js ]; then
|
||||
OPENCLAW_ENTRY="dist/index.js"
|
||||
else
|
||||
echo "Missing dist/index.(m)js (build output):"
|
||||
ls -la dist || true
|
||||
exit 1
|
||||
fi
|
||||
export OPENCLAW_ENTRY
|
||||
|
||||
home_dir=$(mktemp -d "/tmp/openclaw-plugins-e2e.XXXXXX")
|
||||
export HOME="$home_dir"
|
||||
@@ -38,7 +48,7 @@ JS
|
||||
}
|
||||
JSON
|
||||
|
||||
node dist/index.js plugins list --json > /tmp/plugins.json
|
||||
node "$OPENCLAW_ENTRY" plugins list --json > /tmp/plugins.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
@@ -99,8 +109,8 @@ JS
|
||||
JSON
|
||||
tar -czf /tmp/demo-plugin-tgz.tgz -C "$pack_dir" package
|
||||
|
||||
node dist/index.js plugins install /tmp/demo-plugin-tgz.tgz
|
||||
node dist/index.js plugins list --json > /tmp/plugins2.json
|
||||
node "$OPENCLAW_ENTRY" plugins install /tmp/demo-plugin-tgz.tgz
|
||||
node "$OPENCLAW_ENTRY" plugins list --json > /tmp/plugins2.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
@@ -145,8 +155,8 @@ JS
|
||||
}
|
||||
JSON
|
||||
|
||||
node dist/index.js plugins install "$dir_plugin"
|
||||
node dist/index.js plugins list --json > /tmp/plugins3.json
|
||||
node "$OPENCLAW_ENTRY" plugins install "$dir_plugin"
|
||||
node "$OPENCLAW_ENTRY" plugins list --json > /tmp/plugins3.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
@@ -192,8 +202,8 @@ JS
|
||||
}
|
||||
JSON
|
||||
|
||||
node dist/index.js plugins install "file:$file_pack_dir/package"
|
||||
node dist/index.js plugins list --json > /tmp/plugins4.json
|
||||
node "$OPENCLAW_ENTRY" plugins install "file:$file_pack_dir/package"
|
||||
node "$OPENCLAW_ENTRY" plugins list --json > /tmp/plugins4.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
|
||||
@@ -7,9 +7,9 @@ import { join, resolve } from "node:path";
|
||||
type PackFile = { path: string };
|
||||
type PackResult = { files?: PackFile[] };
|
||||
|
||||
const requiredPaths = [
|
||||
"dist/index.js",
|
||||
"dist/entry.js",
|
||||
const requiredPathGroups = [
|
||||
["dist/index.js", "dist/index.mjs"],
|
||||
["dist/entry.js", "dist/entry.mjs"],
|
||||
"dist/plugin-sdk/index.js",
|
||||
"dist/plugin-sdk/index.d.ts",
|
||||
"dist/build-info.json",
|
||||
@@ -82,7 +82,14 @@ function main() {
|
||||
const files = results.flatMap((entry) => entry.files ?? []);
|
||||
const paths = new Set(files.map((file) => file.path));
|
||||
|
||||
const missing = requiredPaths.filter((path) => !paths.has(path));
|
||||
const missing = requiredPathGroups
|
||||
.flatMap((group) => {
|
||||
if (Array.isArray(group)) {
|
||||
return group.some((path) => paths.has(path)) ? [] : [group.join(" or ")];
|
||||
}
|
||||
return paths.has(group) ? [] : [group];
|
||||
})
|
||||
.toSorted();
|
||||
const forbidden = [...paths].filter((path) =>
|
||||
forbiddenPrefixes.some((prefix) => path.startsWith(prefix)),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user