zlh-grind/Session_Summaries/2026-03-21_IDE-Proxy-Working.md

2.8 KiB
Raw Blame History

2026-03-21 Dev IDE proxy working end-to-end

Summary

After significant debugging, the browser IDE is fully working through the API proxy. This was a non-trivial integration involving multiple interacting issues that had to be resolved in sequence.


What Was Fixed

1. Token bootstrap — fixed new-tab auth loss

Direct tab navigation loses Authorization: Bearer headers.

Solution: POST /api/dev/:id/ide-token returns a signed token. Bootstrap route GET /api/dev/:id/ide?token=... validates it, sets an HTTP-only IDE cookie, then redirects into the live tunnel.

2. Bootstrap vs live traffic separation

Routing all traffic through /api/dev/:id/ide caused interference with normal API route behavior.

Solution: split into two paths:

  • bootstrap: /api/dev/:id/ide
  • live tunnel: /__ide/:id/*

3. Correct upstream port

Original assumption was 6000. Chrome blocks port 6000 as unsafe. Agent was updated to expose code-server on 8080. API proxy updated to target 8080.

4. Host header

code-server expects the browser-facing host preserved through the proxy.

Changed Host header from container host to req.headers.host (browser host). Matches official code-server reverse-proxy guidance.

5. Origin override removed

Forcing Origin to backend target conflicted with browser-facing Host. Changed to pass browser Origin through only when present.

6. WS target fallback bug — the main fix

HTTP requests were correctly targeting the container. WS requests were falling back to 127.0.0.1:8080.

Logs confirmed: ECONNREFUSED 127.0.0.1:8080

Root cause: shared proxy WS handling was losing per-request target context.

Fix: disabled WS on the shared /__ide HTTP proxy. Handled WebSocket upgrades only in attachDevProxyServer(server). Built a target-bound WS proxy instance at upgrade time using the resolved container target. That eliminated the localhost fallback entirely.


Working Flow

1. frontend → POST /api/dev/:id/ide-token
2. API returns /api/dev/:id/ide?token=...
3. frontend opens URL in new tab
4. bootstrap validates token, sets IDE cookie, redirects to /__ide/:id/
5. live traffic proxied through /__ide/:id/*
6. API proxies HTTP + WS to http://<container-ip>:8080

Files Involved

  • src/routes/devProxy.js
  • src/app.js
  • src/auth/tokens.js

Current Limitations

  • browser still sees API host/IP until portal is behind a proper domain/reverse proxy
  • host-based dev-<vmid>.zlh.dev routing started but reverted — bootstrap path is canonical
  • service workers require HTTPS — extensions may not fully load until portal is behind SSL

Next

  • Portal "Open IDE" button implementation
  • Portal behind HTTPS/domain (unblocks service workers and extension loading)
  • Headscale/Tailscale for local dev access (SSH, VS Code Remote)