forked from molecule-ai/molecule-core
Single-container tenant architecture: Go platform (:8080) + Canvas Node.js (:3000) in one Fly machine, with Go's NoRoute handler reverse- proxying non-API routes to the canvas. Browser only talks to :8080. Changes: platform/Dockerfile.tenant — multi-stage build (Go + Node + runtime). Bakes workspace-configs-templates/ + org-templates/ into the image. Build context: repo root. platform/entrypoint-tenant.sh — starts both processes, kills both if either exits. Fly health check on :8080 covers the Go binary; canvas health is implicit (proxy returns 502 if canvas is down). platform/internal/router/canvas_proxy.go — httputil.ReverseProxy that forwards unmatched routes to CANVAS_PROXY_URL (http://localhost:3000). Activated by NoRoute when CANVAS_PROXY_URL env is set. platform/internal/router/router.go — wire NoRoute → canvasProxy when CANVAS_PROXY_URL is present; no-op otherwise (local dev unchanged). platform/internal/middleware/securityheaders.go — relaxed CSP to allow Next.js inline scripts/styles/eval + WebSocket + data: URIs. The strict `default-src 'self'` was blocking all canvas rendering. canvas/src/lib/api.ts — changed `||` to `??` for NEXT_PUBLIC_PLATFORM_URL so empty string means "same-origin" (combined image) instead of falling back to localhost:8080. canvas/src/components/tabs/TerminalTab.tsx — same `??` fix for WS URL. Verified: tenant machine boots, canvas renders, 8 runtime templates + 4 org templates visible, API routes work through the same port. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
36 lines
915 B
Bash
36 lines
915 B
Bash
#!/bin/sh
|
|
# Tenant entrypoint — starts both Go platform (API) and Canvas (UI).
|
|
#
|
|
# Go platform listens on :8080 (Fly health checks hit this port).
|
|
# Canvas Node.js listens on :3000 (internal only).
|
|
# The Go platform's fallback handler proxies non-API routes to :3000
|
|
# so the browser only ever talks to :8080.
|
|
#
|
|
# If either process dies, we kill the other and exit non-zero so Fly
|
|
# restarts the machine.
|
|
|
|
set -e
|
|
|
|
# Start Canvas in background
|
|
cd /canvas
|
|
PORT=3000 HOSTNAME=0.0.0.0 node server.js &
|
|
CANVAS_PID=$!
|
|
|
|
# Start Go platform in foreground-ish (we trap signals)
|
|
cd /
|
|
/platform &
|
|
PLATFORM_PID=$!
|
|
|
|
# If either process exits, kill the other
|
|
cleanup() {
|
|
kill $CANVAS_PID 2>/dev/null || true
|
|
kill $PLATFORM_PID 2>/dev/null || true
|
|
}
|
|
trap cleanup EXIT SIGTERM SIGINT
|
|
|
|
# Wait for either to exit — whichever exits first triggers cleanup
|
|
wait -n $CANVAS_PID $PLATFORM_PID
|
|
EXIT_CODE=$?
|
|
cleanup
|
|
exit $EXIT_CODE
|