feat: Add browser-based VS Code extension preview environment#273
Merged
feat: Add browser-based VS Code extension preview environment#273
Conversation
Add preview infrastructure for code-server on Heroku Review Apps: - preview/Dockerfile: code-server container with Debrief extension + Python services - preview/entrypoint.sh: startup script with $PORT binding for Heroku - preview/workspace/: VS Code workspace with sample STAC + REP data - preview/workspace/WELCOME.md: reviewer onboarding document - app.json + heroku.yml: Heroku Review Apps deployment descriptors - tests/e2e/test-preview-smoke.spec.ts: Playwright smoke test - Taskfile.yml: preview:build, preview:run, preview:package tasks - Evidence and media artifacts for PR Phase 1 (Before Heroku Config) is complete. Phase 2 requires manual Heroku Review Apps configuration by the repository owner. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
Documents the two blockers (no nftables for Docker, no openvscode-server binary) preventing preview smoke tests from running in sandboxed cloud sessions, with minimum reproducible example and three solution options. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
Remove options that bypass Docker (openvscode-server, npm code-server) since they don't validate the Dockerfile that Heroku will actually run. Focus on fixing Docker networking in the sandbox via --iptables=false --bridge=none with host networking. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
…kit-099-8dlMl # Conflicts: # docs/project_notes/code-server-cloud-testing.md # tests/e2e/test-preview-smoke.spec.ts
Heroku uses the Dockerfile's parent directory as the Docker build context. With the Dockerfile in preview/, COPY commands for services/ and shared/ failed because they were outside the build context. Moving to Dockerfile.preview at repo root fixes this. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
The Heroku build fails at COPY apps/vscode/*.vsix because no pre-built .vsix exists in the repo. Restructure Dockerfile.preview as a multi-stage build: Stage 1 uses node:18-slim with pnpm to build the VS Code extension and package the .vsix, Stage 2 copies it into the code-server image. This makes the Docker build fully self-contained — no pre-build step needed. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
undici@7.18.2 (pulled in by @vscode/vsce) uses the global File class which is only available in Node 20+. This was causing the Heroku preview build to fail with "ReferenceError: File is not defined". https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
The extension was installed as root, placing it in /root/.local/share/ code-server/extensions/. But code-server runs as the coder user and looks in /home/coder/.local/share/code-server/extensions/, so the extension was invisible at runtime. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
- Add --force flag to code-server --install-extension - Add build-time verification step (--list-extensions + ls extensions dir) - Add runtime diagnostics to entrypoint to log installed extensions - Open .code-workspace file instead of folder directory so workspace settings (including debrief.stacCatalogPath) are applied https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
- Add .dockerignore to exclude node_modules, .git, docs, specs, test files from Docker build context - Replace code-server --list-extensions (starts full server) with lightweight ls + grep check to avoid resource pressure during build - Simplify entrypoint diagnostics to avoid starting code-server twice The previous build failed silently at Step 13 — likely Docker OOM when committing the node_modules layer. These changes reduce resource usage. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
The build was dying silently after pnpm install (Step 13/42) — Docker could not commit the ~500MB node_modules layer on Heroku's constrained build dynos. Fix: merge install + build + package + rm node_modules into one RUN. Docker layers store diffs, so creating and deleting node_modules in the same command means the committed layer is tiny (~1MB .vsix only). Also removed the separate COPY-package.json-then-COPY-source pattern — Heroku has no Docker layer cache, so the caching benefit was zero while the extra layers added resource pressure. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
COPY creates files owned by root regardless of USER directive. The rm after install-extension failed with "Operation not permitted" because coder can't delete a root-owned file. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
Three defensive changes to ensure the Debrief extension appears: 1. Add .vscodeignore — ensures the vsix only contains dist/, resources/, package.json, and README.md (excludes src/, tests, configs) 2. Add onStartupFinished activation event — triggers extension activation on startup regardless of which views are visible, improving compatibility with code-server 3. Add comprehensive Dockerfile diagnostics — the build now prints code-server version, lists installed extensions, and verifies the extension entry point exists. This will reveal the root cause if the extension still doesn't load. Also suppresses code-server walkthrough page via workspace settings. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
…#7326) code-server's --install-extension at Docker build time writes to extensions.json, but this manifest can be lost at runtime — a known issue (coder/code-server#7326). Move extension installation to the entrypoint script so it runs at container startup, ensuring the extensions.json is always fresh. Also restructure activate() into 4 phases for resilience: - Phase 1: Services init with try-catch around ConfigService - Phase 2: View provider registration (EARLY, before async work) - Phase 3: Activity bar, context, filesystem, commands - Phase 4: Background Python service checks https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
Webview panels were blank in code-server because script-src relied on cspSource origin matching, which can fail in code-server's remote context. Switching to nonce-based CSP bypasses origin checks entirely. Also pre-seeds ~/.config/debrief/config.json in entrypoint.sh so the STAC Stores tree populates with sample data on first launch. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
Strip diagnostic echoes from entrypoint, remove build-time version check RUN layer, and drop --log trace from code-server startup. https://claude.ai/code/session_01NJ39Sc6BUKHbQTzXPy8Zo2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
preview/directory with Dockerfile, entrypoint, sample STAC/REP data, and workspace configapp.jsonandheroku.ymlat repo root enable automatic PR preview deployments once Review Apps are configuredChanges
Phase 1: Container & Infrastructure
preview/Dockerfilebased oncodercom/code-server:latestpreview/entrypoint.sh— binds to$PORT, installs.vsix, opens default workspacepreview/workspace/debrief-preview.code-workspacewith sample data pathsPhase 2: Sample Data & Workspace
preview/workspace/samples/preview/workspace/WELCOME.mdonboarding document for reviewersPhase 3: Heroku Deployment Descriptors
app.jsonwith Review Apps configurationheroku.ymlwith container stack definitionpreview:build,preview:run,preview:packagetasks toTaskfile.ymlPhase 4: Testing & Evidence
tests/e2e/test-preview-smoke.spec.tswith 5 checks:Evidence
Code-Server Screenshot
VS Code workbench running in browser via code-server, showing the test workspace with sample data and STAC stores panel.
Test Results
No regressions — this feature is infrastructure-only; no application code was modified.
Usage Example