fix(skill): derive registry URL for default installs

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
XiaoSeS 2026-09-04 10:53:02 +08:00
parent 5f17e7a181
commit b4616e60fd
3 changed files with 53 additions and 2 deletions

View file

@ -19,7 +19,7 @@ port=18080
tmp=$(mktemp -d)
cleanup() {
docker rm -f "$name" "$name-fixed" >/dev/null 2>&1 || true
docker rm -f "$name" "$name-fixed" "$name-default" >/dev/null 2>&1 || true
rm -rf "$tmp"
}
trap cleanup EXIT
@ -126,6 +126,45 @@ fi
docker rm -f "$name" >/dev/null 2>&1 || true
# With no explicit public URL, the guide must derive the registry from the
# sanitized request scheme, Host (including port), and deployment base path.
default_html="$tmp/default-html"
mkdir -p "$default_html/assets" "$default_html/install" "$default_html/registry"
printf '%s\n' 'INDEX_HTML_MARKER' >"$default_html/index.html"
cp "$ROOT_DIR/web/src/docs/skill.md.template" "$default_html/registry/skill.md.template"
cp "$ROOT_DIR/web/runtime-config.js.template" "$default_html/runtime-config.js.template"
name_default="$name-default"
port_default=18082
docker run -d --name "$name_default" \
-p "$port_default:80" \
-e SKILLHUB_API_UPSTREAM=http://127.0.0.1:9 \
-e SKILLHUB_TRUST_FORWARDED_PROTO=false \
-e SKILLHUB_WEB_BASE_PATH=/ \
-v "$default_html:/usr/share/nginx/html" \
-v "$ROOT_DIR/web/nginx.conf.template:/etc/nginx/templates/default.conf.template:ro" \
-v "$entrypoint_d/20-base-path.sh:/docker-entrypoint.d/20-base-path.sh:ro" \
-v "$entrypoint_d/30-runtime-config.sh:/docker-entrypoint.d/30-runtime-config.sh:ro" \
"$NGINX_IMAGE" >/dev/null
default_base="http://127.0.0.1:$port_default"
i=0
until curl -fsS -o /dev/null "$default_base/nginx-health" 2>/dev/null; do
i=$((i + 1))
if [ "$i" -ge 30 ]; then
echo 'nginx (default public URL) did not become ready' >&2
docker logs "$name_default" >&2 || true
exit 1
fi
sleep 1
done
default_guide=$(curl -fsS "$default_base/install/skillhub.md")
printf '%s' "$default_guide" | grep -F "The primary registry for this guide is \`$default_base\`." >/dev/null
if printf '%s' "$default_guide" | grep -F '__SKILLHUB_PUBLIC_BASE_URL__' >/dev/null; then
echo 'default Agent guide must not expose the runtime URL marker' >&2
exit 1
fi
docker rm -f "$name_default" >/dev/null 2>&1 || true
# Fixed-base image served via the bundled deploy configs: assets are baked under
# /fixed/, a baked-base marker is present, and SKILLHUB_WEB_BASE_PATH is passed as
# an empty string (as compose.release.yml / k8s do). Routing must follow the baked

View file

@ -24,7 +24,13 @@ envsubst '${SKILLHUB_WEB_API_BASE_URL} ${SKILLHUB_PUBLIC_BASE_URL} ${SKILLHUB_WE
# Generate both the preferred install guide and the compatibility route from
# one template so self-hosted deployments keep their own registry URL.
mkdir -p /usr/share/nginx/html/install
envsubst '${SKILLHUB_PUBLIC_BASE_URL}' \
guide_public_base_url="$SKILLHUB_PUBLIC_BASE_URL"
if [ -z "$guide_public_base_url" ]; then
# Nginx replaces this marker from the sanitized request scheme, Host, and
# configured base path. This keeps zero-config self-hosted installs usable.
guide_public_base_url='__SKILLHUB_PUBLIC_BASE_URL__'
fi
SKILLHUB_PUBLIC_BASE_URL="$guide_public_base_url" envsubst '${SKILLHUB_PUBLIC_BASE_URL}' \
< /usr/share/nginx/html/registry/skill.md.template \
> /usr/share/nginx/html/registry/skill.md
cp /usr/share/nginx/html/registry/skill.md /usr/share/nginx/html/install/skillhub.md

View file

@ -75,6 +75,9 @@ server {
location = /registry/skill.md {
default_type text/plain;
sub_filter_types text/plain;
sub_filter_once off;
sub_filter '__SKILLHUB_PUBLIC_BASE_URL__' '$proxy_x_forwarded_proto://$http_host$skillhub_forwarded_prefix';
add_header Cache-Control "no-cache";
add_header Content-Disposition "inline";
add_header X-Content-Type-Options "nosniff";
@ -83,6 +86,9 @@ server {
location = /install/skillhub.md {
default_type text/plain;
sub_filter_types text/plain;
sub_filter_once off;
sub_filter '__SKILLHUB_PUBLIC_BASE_URL__' '$proxy_x_forwarded_proto://$http_host$skillhub_forwarded_prefix';
add_header Cache-Control "no-cache";
add_header Content-Disposition "inline";
add_header X-Content-Type-Options "nosniff";