niklas-stephan.de site: Astro rewrite with Wiki.js MCP content source (nsde container)
Last updated 06/11/2026 · handtrixxx, website, astro, wikijs, mcp, migrated-from-outline
- kb-id:
site-astro-rewrite - importance: high
- tags: handtrixxx,website,astro,wikijs,mcp,migrated-from-outline
- updated: 2026-11-06
- summary: niklas-stephan.de rewritten Hugo+Outline Astro 5; content synced Wiki.js via MCP endpoint; nsde container builds on boot and rebuilds every REFRESH_MINUTES. Staging live at qas.niklas-stephan.de; production swap pending approval.
Current state (since 2026-11-06)
- Repo: Gitea
handtrixxx/niklas-stephan.de(main). Old Hugo/Outline pipeline (hugo/, scripts/, nginx/) removed; site is Astro 5 static site at repo root. - Content source: Wiki.js MCP at
https://wiki.niklas-stephan.de/_mcp(bearerWIKI_MCP_TOKEN), path prefixes fromWIKI_PATHS(defaultkb,home). Loadersrc/loaders/wiki.tscaches pages in.wiki-cache/keyed onupdatedAt, retries on HTTP 429 backoff, strips kb header block, converts{.is-info}admonitions callout divs, absolutizes root-relative image URLs. - Loader also generates
public/search-index.json(fuse.js client search at /search/) andpublic/rss.xml;@astrojs/sitemapregistered inintegrationsprovides/sitemap-index.xml+/sitemap-0.xml. - Static pages about/imprint/privacy live in
src/pages-static/; wiki pages served under/wiki/<path>/. - Container: node:22-alpine;
scripts/start.mjsservesdist/on port 80, runsnpm run buildon boot and everyREFRESH_MINUTES(default 60). Traefik routing unchanged (niklas-stephan.de, www, handtrixxx.com, www; certresolver letsencrypt-tls; service nsde port 80). - Deploy env (
/data/docker/niklas-stephan.de/.envon handtrixxx.com) needsWIKI_MCP_TOKEN,WIKI_PATHS=kb,home,REFRESH_MINUTES,SITE_BASE_URL. Token also in/data/ai-persistence/.env.
Staging: qas.niklas-stephan.de (live since 2026-11-06)
- Dir
/data/docker/qas.niklas-stephan.deon handtrixxx.com; compose servicensde-qas, imagegit.handtrixxx.com/handtrixxx/niklas-stephan.de:qas, Traefik routernsde-qaswithHost(qas.niklas-stephan.de)and certresolverletsencrypt-tls(TLS challenge works because the subdomain already resolves to 148.251.15.253),REFRESH_MINUTES=15. The repo ships this compose asqas.example.yml. - Verified over HTTPS: home,
/wiki/kb/…pages, /search/, /rss.xml, /sitemap-index.xml (73 URLs), /robots.txt, /humans.txt all 200; boot rebuild built 74 pages./blog/404 is expected (no blog pages in the wiki yet).
Gotchas verified 2026-11-06
- MCP
get_pagereturns page as multiple text blocks (metadata JSON first, then markdown body);search_pageslimit caps at 25, paginate offset. - Astro 5:
sitemap: truein astro.config does nothing by itself; registerintegrations: [sitemap()], and the files aresitemap-index.xml/sitemap-0.xml, notsitemap.xml. - Dockerfile build step runs before runtime env set, so initial dist has only static pages; boot rebuild in start.mjs compensates (pulls wiki immediately on start).
- Docker
COPY a b scripts ./flattens scripts directory into ./ — copyscriptsseparately. - Gitea repo is not anonymously cloneable (404); clone with auth or copy tree.
- Copying the repo tree into a deploy directory overwrites that directory’s
compose.yml: the repo-root compose is the production one (containernsde). On qas this madedocker compose uptry to create a secondnsdecontainer (failed with name conflict, production untouched). Keep the staging compose outside the tar or restore it after copying.
Not yet done
- Production
nsdecontainer still runs old Hugo image; deploy new image only after Niklas approves.
Source: Wiki.js