mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:07:04 +01:00
static_site_caddy.sh is the one site-block body for the personal website and kcd2 dice Caddies: prerendered paths, real 404s and the ai-catalog Link header instead of an SPA catch-all. Both setup scripts gain a sudo-free `serve` that recreates only their container; kcd2's readiness wait needs a 200. redeploy_agent_ready_sites.sh serves both, restarts the popes site and runs the AgentReady checker against all three public URLs. Tested by test_static_site_serve.sh, test_redeploy_agent_ready_sites.sh and the caddy:2.8 e2e_agent_ready_caddy.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBScELfMUiieK9ManFbS3Y
67 lines
2.4 KiB
Bash
Executable File
67 lines
2.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Shared site-block body for the loopback static-site Caddies.
|
|
#
|
|
# Sourced by website_build.sh and kcd2_serve.sh, which each wrap this in their
|
|
# own global options and site address. One copy, because both serve a
|
|
# prerendered dist/ that must pass AgentReady (~/src/utils/agent_ready) and the
|
|
# two blocks drifting apart is how one of them grew an SPA catch-all.
|
|
#
|
|
# Check end to end with tests/e2e_agent_ready_caddy.sh website|dice.
|
|
|
|
# `serve` guard: refuse before docker sees the bind-mount source. A missing
|
|
# dist/ is not an error to compose -- docker creates it as an empty root-owned
|
|
# directory inside the repo and the site 404s while "running".
|
|
static_site_require_dist() {
|
|
[[ -f "$1/index.html" ]] || die "No build at $1 — run setup first."
|
|
}
|
|
|
|
# Prints the directives that go inside the ":<port> { ... }" block.
|
|
static_site_caddy_body() {
|
|
cat <<'EOF'
|
|
root * /srv
|
|
encode gzip
|
|
# AgentReady FIND-04: advertise the AI catalog in an HTTP header as well
|
|
# as in the page head.
|
|
header Link "</.well-known/ai-catalog.json>; rel=\"ai-catalog\"; type=\"application/ai-catalog+json\""
|
|
# Exact types the agent spec asks for. Go's defaults are text/xml and
|
|
# application/json, and a .md would otherwise be guessed per platform.
|
|
# The "file" matcher limits each to files that exist, so a missing
|
|
# /x.md 404s as the HTML 404 page rather than as markdown.
|
|
@md {
|
|
path *.md
|
|
file
|
|
}
|
|
header @md Content-Type "text/markdown; charset=utf-8"
|
|
@txt {
|
|
path /robots.txt /llms.txt
|
|
file
|
|
}
|
|
header @txt Content-Type "text/plain; charset=utf-8"
|
|
@sitemap {
|
|
path /sitemap.xml
|
|
file
|
|
}
|
|
header @sitemap Content-Type "application/xml"
|
|
@catalog {
|
|
path /.well-known/ai-catalog.json
|
|
file
|
|
}
|
|
header @catalog Content-Type "application/ai-catalog+json"
|
|
# {path}/index.html is the load-bearing middle term: every route is
|
|
# prerendered to dist/<route>/index.html (blog posts, /how-it-works/),
|
|
# and try_files does NOT resolve a directory to its index on its own.
|
|
# Without it those pages 404 instead of serving their own HTML.
|
|
#
|
|
# There is deliberately no /index.html catch-all after it: that SPA
|
|
# fallback answered every unknown path, robots.txt typo or probe with
|
|
# "200 text/html", which agents read as a soft 404.
|
|
try_files {path} {path}/index.html
|
|
file_server
|
|
# The prerendered 404 page, keeping the 404 status.
|
|
handle_errors 404 {
|
|
rewrite * /404.html
|
|
file_server
|
|
}
|
|
EOF
|
|
}
|