FigJam Diagram: Wiki.js — Documentation Platform (expires 2026-04-13)
Internal documentation platform for the k3s homelab. Forked from upstream Wiki.js to add Mermaid 11 diagram support and an MCP server for Claude integration.
| Internal URL | https://wiki.k3s.internal.strommen.systems (internal LAN only) |
| Namespace | wiki |
| Image | harbor.k3s.internal.strommen.systems/staging/wiki:latest |
| Fork | zolty-mat/wiki — Mermaid 11 upgrade + MCP server |
| Auth | No external auth — internal LAN only, no public route |
| Pod Security | pod-security.kubernetes.io/enforce: restricted |
Image tag note:
staging/wiki:latest— internal documentation tool,:latesttag is acceptable here (not production Harbor project). SHA-based tagging planned but not yet adopted.
Wiki.js is internal only — there is no public IngressRoute and no Authentik forwardAuth. Access requires LAN connectivity or VPN.
The internal Ingress uses wiki-wiki-security-headers@kubernetescrd middleware (HSTS, CSP, XSS protection).
Deployed image from zolty-mat/wiki, a fork of Wiki.js with:
flowchart, new graph syntax, better node shapes)wiki_read_page, wiki_update_page, wiki_create_page, wiki_search, wiki_list_pages, wiki_list_tags via @modelcontextprotocol/sdk| StatefulSet | postgres |
| Database | wikijs |
| User | wikijs |
| PVC | postgres-data — 2Gi Longhorn |
| Backups | postgres-backup CronJob — daily 3:30 AM UTC, 7-day retention → S3 |
Secret bootstrap:
kubectl create secret generic postgres-credentials -n wiki \
--from-literal=POSTGRES_USER=wikijs \
--from-literal=POSTGRES_PASSWORD="$(openssl rand -base64 32)" \
--from-literal=POSTGRES_DB=wikijs
Security note: Prior to 2026-04-05 the
postgres-credentialsSecret was committed towiki.yamlwith a plaintext password. Removed — Secret is now created out-of-band. Rotation recommended: update the in-cluster secret and restart postgres + wiki pods.
Daily at 03:30 UTC → s3://k3s-homelab-backups-855878721457/postgres-backups/wiki/. Retention: 7 days.
AWS credentials in postgres-backup-aws-credentials secret (IAM user k3s-backups).
kubectl create secret generic postgres-backup-aws-credentials -n wiki \
--from-literal=AWS_ACCESS_KEY_ID="<from-terraform-output>" \
--from-literal=AWS_SECRET_ACCESS_KEY="<from-terraform-output>"
| Header | Value |
|---|---|
| HSTS | 1 year, includeSubdomains, preload |
| CSP | default-src 'self', unsafe-inline for scripts/styles (Wiki.js requirement) |
| X-Frame-Options | DENY |
| X-Content-Type-Options | nosniff |
| Referrer-Policy | same-origin |
| Component | runAsUser | fsGroup | seccompProfile | allowPrivilegeEscalation | capabilities |
|---|---|---|---|---|---|
| PostgreSQL | 999 | 999 | RuntimeDefault | false | drop: ALL |
| Wiki.js | 1000 | 1000 | RuntimeDefault | false | drop: ALL |
Ingress to wiki pod: Traefik (kube-system) → :3000, Prometheus (monitoring) → :3000, Cluster Dashboard (default) → :3000
Egress from wiki pod: PostgreSQL (same namespace) :5432, CoreDNS :53, Authentik (authentik ns) :9000/:9443, Internet :80/:443
Claude Code connects to Wiki.js via the GraphQL API using an MCP server.
| GraphQL endpoint | https://wiki.k3s.internal.strommen.systems/graphql |
| Auth | API Key — stored in ~/.zshrc as WIKIJS_API_TOKEN |
| Key location | Wiki.js Admin → API Keys (Key ID 5, admin group) |
| Key expiry | ~1 year (check expiry in Admin → API Keys) |
| MCP tools | wiki_read_page, wiki_update_page, wiki_create_page, wiki_list_pages, wiki_search, wiki_list_tags |
Permission gotcha: If tools return "not authorized" errors, the fix is NOT a new token — it's ensuring Admin → Groups → Group 1 has
read:pagespermission enabled in the Wiki.js admin UI.
Bootstrap (after rotating key):
WIKIJS_API_TOKEN in ~/.zshrckubernetes/apps/wiki/
wiki.yaml — Namespace (pod-security: restricted), PVC, PostgreSQL StatefulSet (postgres:16.13-alpine),
Services, ConfigMap, Deployment (wiki), Ingress, SecurityHeaders
Middleware, NetworkPolicy, PodDisruptionBudget
postgres-backup-cronjob.yaml — Daily PostgreSQL backup to S3 (3:30 AM UTC)