KB-49FE
Branch A — Static Hosting Option Analysis
3 min read Revision 1
ai-workspaceui-previewhostingnginxnuxtanalysis2026-05-29
Branch A — Static Hosting Option Analysis
Hard Gate 0 findings (host facts)
- Host = contabo VPS
vmi3080463(root); confirms apply channel. - Containers:
incomex-nginx(nginx:alpine, :80/:443),incomex-nuxt(SSR :8080),incomex-directus,incomex-agent-data,incomex-claude-kb,incomex-claude-mcp,incomex-qdrant,postgres,uptime-kuma. - nginx mounts (key):
/opt/incomex/docker/nginx/conf.d→/etc/nginx/conf.d(ro);/opt/incomex/docker/nginx/static→/usr/share/nginx/static(ro) ← existing static mount. vps.incomexsaigoncorp.vnserver block (443) already serves static files viaalias(e.g./api/openapi.json).location /proxies everything else tonuxt_backend.- Strict CSP at server level allows
script-src 'self' 'unsafe-inline' 'unsafe-eval',style-src 'self' 'unsafe-inline',connect-src 'self'— compatible with a self-contained static preview.
Options compared
| Criterion | A. nginx static route (existing mount) | B. Nuxt public/static dir | C. Separate static container | D. GitHub Pages |
|---|---|---|---|---|
| Every AI reachable by URL | ✅ same domain | ✅ | ✅ (new vhost/port) | ✅ external |
| Easy for Claude Code to deploy | ✅ write host dir + 1 route | ⚠️ risks Nuxt build/app | ⚠️ new compose service | ⚠️ needs repo/push/secrets |
| Isolated from production | ✅ separate path/dir | ❌ inside prod app tree | ✅ strong | ✅ fully external |
| Versioned previews | ✅ /…/<version>/ |
✅ | ✅ | ✅ |
| Rollback easy | ✅ restore conf .bak + rm dir | ⚠️ tied to app deploy | ⚠️ stop service | ✅ revert commit |
| HTML/CSS/JS/mock JSON | ✅ | ✅ | ✅ | ✅ |
| Risk to Nuxt prod app | ✅ none (no app touch) | ❌ high (shares app) | ✅ none | ✅ none |
| Extra infra / restart needed | ✅ none (reload only) | ❌ rebuild | ❌ container recreate | ⚠️ external dependency, data leaves VPS |
Recommendation: Option A — reuse the existing nginx static mount
Rationale:
- The mount
/opt/incomex/docker/nginx/staticalready exists and is read-only inside the container — so writing previews on the host needs no container recreation, no new volume, no Nuxt rebuild. - A single additive
location /ui-preview/block is the only config change; rollback = restore one.bak. - Keeps everything on the trusted domain (no data leaving the VPS — matters because specs/mock can reflect internal process structure).
- B is rejected (couples previews to the production app — violates "no overwrite of production app").
- C is viable but heavier (new compose service + restart risk) for no benefit over A here.
- D is a fine fallback if the VPS is ever unavailable, but it pushes drafts off-VPS (against "VPS preview = canonical visual SoT").