유대선
프로젝트로
·트러블슈팅·3

The cloud was dead: a wrong domain, missing env, a stale build, and a pnpm-monorepo deploy wall

Clicking '클라우드 열기' from the desktop went nowhere. Four problems were stacked on top of each other — a domain that didn't exist, a deploy built without Supabase env, a build 3 days stale, and a pnpm workspace Vercel couldn't remote-build. The fix was a local build + prebuilt static deploy, and then the terminal cockpit actually embedded inside the cloud page (after I'd wrongly warned it couldn't).

Symptom

The desktop has a "🛰 원격 → 클라우드 열기" button. Clicking it:

This site can't be reached
app.talkak.daeseon.ai's server IP address could not be found.
ERR_NAME_NOT_RESOLVED

Pointing it at the real deploy instead gave a black page with one red line:

로그인 미설정 — VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY (.env.local) 필요.

Cause — four problems, stacked

Peeling them one at a time:

  1. The button pointed at a domain that was never wired. I had hardcoded app.talkak.daeseon.ai as the "always-on" cloud URL — aspirational, no DNS. My bug.
  2. The live deploy had no Supabase env. dist-gilt-gamma-69.vercel.app returned HTTP 200 and the right <title>, but the bundle was built without VITE_SUPABASE_*, so Supabase never initialized → login impossible.
  3. The deploy was ~3 days stale. age on the response was ~291,000s. Everything I'd built that day — per-entity /e/<slug> pages, the cockpit embed — was on the Mac only. /e/test404. Build ≠ deploy: code on your machine is invisible to the cloud until a deploy carries it there.
  4. Vercel couldn't remote-build it. vercel --prod from apps/web failed at npm installapps/web depends on workspace packages (@ddalkkak/*) that don't exist on npm, and Vercel only uploads the subdirectory, not the pnpm workspace root.

Fix — build locally, deploy prebuilt

The monorepo wall is the interesting one. The answer is to never let Vercel install or build: do it locally where pnpm resolves the workspace, then ship the static output.

# locally: pnpm resolves @ddalkkak/*, and apps/web/.env bakes VITE_SUPABASE_* into the bundle
pnpm --filter web build
grep -l "supabase.co" apps/web/dist/assets/index-*.js   # verify the URL is actually baked in
 
# hand Vercel a finished build via the Build Output API — no install, no build on their side
vercel link --yes --project talkak-app --scope <scope>
mkdir -p .vercel/output/static && cp -R dist/. .vercel/output/static/
cat > .vercel/output/config.json <<'JSON'
{ "version": 3, "routes": [ { "handle": "filesystem" }, { "src": "/.*", "dest": "/index.html" } ] }
JSON
vercel deploy --prebuilt --prod

The config.json is the SPA fallback the old deploy was missing: serve real files first (handle: filesystem), then rewrite everything else to index.html so /e/<slug> deep-links resolve client-side. Vercel also rejected an illegal "comment" key I'd left in vercel.json — its schema is strict.

Result (curl-verified): https://talkak-app.vercel.app → 200, /e/test → 200, supabase.co present in the bundle. The Supabase anon key is client-safe by design (RLS guards the data), so baking it into the public bundle is correct, not a leak.

The part where the founder was right and I was wrong

I'd warned that the terminal cockpit couldn't be embedded inside the cloud page: the page is HTTPS, the cockpit serves plain HTTP, and browsers block active mixed content. He opened it anyway — and the terminal rendered fine inside the page.

I was wrong, and the reason is worth keeping: http://localhost is a "potentially trustworthy" origin, exempt from mixed-content blocking. The cockpit's published local_url is http://localhost:7682, so on the same Mac it embeds happily in an HTTPS page. The honest caveat survives, narrowed: a different device (phone) has no localhost to fall back to, and the Tailscale URL is plain HTTP — so cross-device embedding still needs the cockpit on HTTPS (Tailscale Serve, which needs the tailnet's HTTPS certs enabled; ours showed CertDomains: null). Opening the terminal directly on the phone already works.

We moved the cockpit launcher to the top of the cloud dashboard so it isn't buried under seven area cards.

Pattern