Skip to content

Commit ffa6e94

Browse files
Developerclaude
andcommitted
feat(devcontainer): add vnc server for browser testing and ui preview
- Add VNC packages (xvfb, x11vnc, novnc) to Dockerfile - Create start-vnc.sh script for automated VNC startup - Add VNC coder_app with browser icon in workspace - Configure Traefik routing for external domain access - Add port 6080 forwarding in devcontainer.json VNC accessible at: {owner}-{workspace}-vnc.dev.simpleaccounts.io/vnc.html 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6b18839 commit ffa6e94

4 files changed

Lines changed: 103 additions & 2 deletions

File tree

.coder/template.tf

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,13 @@ resource "coder_agent" "main" {
327327
bash .devcontainer/post-start.sh || echo "⚠️ Post-start script had issues"
328328
fi
329329
330+
# Start VNC server for browser testing
331+
echo "🖥️ Starting VNC server..."
332+
if [ -x /usr/local/bin/start-vnc ]; then
333+
/usr/local/bin/start-vnc &
334+
echo "✅ VNC server started on port 6080"
335+
fi
336+
330337
echo "✅ Workspace ready!"
331338
echo ""
332339
echo "Quick start commands:"
@@ -336,6 +343,8 @@ resource "coder_agent" "main" {
336343
echo "Or from app directories:"
337344
echo " Frontend: cd apps/frontend && npm start"
338345
echo " Backend: cd apps/backend && ./mvnw spring-boot:run"
346+
echo ""
347+
echo "VNC Browser: https://${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-vnc.dev.simpleaccounts.io/vnc.html"
339348
EOT
340349

341350
# Display apps (for web access)
@@ -457,6 +466,24 @@ resource "coder_app" "swagger" {
457466
share = "owner"
458467
}
459468

469+
# VNC Browser for UI testing and preview
470+
# Always enabled - useful for Playwright tests and visual debugging
471+
resource "coder_app" "vnc" {
472+
agent_id = coder_agent.main.id
473+
slug = "vnc"
474+
display_name = "VNC Browser"
475+
icon = "/icon/desktop.svg"
476+
url = "http://localhost:6080/vnc.html?autoconnect=true"
477+
subdomain = true
478+
share = "owner"
479+
480+
healthcheck {
481+
url = "http://localhost:6080"
482+
interval = 10
483+
threshold = 20
484+
}
485+
}
486+
460487
# Main workspace container
461488
resource "docker_container" "workspace" {
462489
# Use pre-built image for fast startup
@@ -629,6 +656,22 @@ resource "docker_container" "workspace" {
629656
value = "8080"
630657
}
631658

659+
# VNC routing (port 6080)
660+
labels {
661+
label = "traefik.http.routers.${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-vnc.rule"
662+
value = "Host(`${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-vnc.dev.simpleaccounts.io`)"
663+
}
664+
665+
labels {
666+
label = "traefik.http.routers.${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-vnc.service"
667+
value = "${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-vnc"
668+
}
669+
670+
labels {
671+
label = "traefik.http.services.${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-vnc.loadbalancer.server.port"
672+
value = "6080"
673+
}
674+
632675
# Depend on database containers and host directory setup
633676
depends_on = [
634677
docker_container.postgres,
@@ -659,6 +702,11 @@ resource "coder_metadata" "workspace_info" {
659702
value = "https://${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-api.dev.simpleaccounts.io"
660703
}
661704

705+
item {
706+
key = "vnc_url"
707+
value = "https://${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-vnc.dev.simpleaccounts.io/vnc.html"
708+
}
709+
662710
item {
663711
key = "postgres_host"
664712
value = "db:5432"

.devcontainer/Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,22 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
8282
libevdev2 \
8383
libnotify4 \
8484
libflite1 \
85+
# VNC packages for browser testing and UI preview
86+
xvfb \
87+
x11vnc \
88+
novnc \
89+
websockify \
8590
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
8691

8792
# Set Playwright to use system Chromium
8893
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
8994
ENV PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium
9095

96+
# VNC configuration
97+
ENV DISPLAY=:99
98+
ENV VNC_PORT=5900
99+
ENV NOVNC_PORT=6080
100+
91101
# Install global npm packages and AI CLI tools
92102
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g npm@latest" 2>&1
93103

@@ -124,6 +134,10 @@ RUN NVM_BIN=$(su vscode -c "source /usr/local/share/nvm/nvm.sh && echo \$(npm pr
124134
COPY --chown=vscode:vscode .devcontainer/install-cli-tools.sh /usr/local/bin/install-cli-tools
125135
RUN chmod +x /usr/local/bin/install-cli-tools
126136

137+
# Copy VNC startup script
138+
COPY --chown=vscode:vscode .devcontainer/start-vnc.sh /usr/local/bin/start-vnc
139+
RUN chmod +x /usr/local/bin/start-vnc
140+
127141
# Provide Cursor CLI shim in PATH (resolves actual binary at runtime)
128142
COPY --chown=vscode:vscode .devcontainer/cursor-cli.sh /usr/local/bin/cursor
129143
RUN chmod +x /usr/local/bin/cursor && ln -sf /usr/local/bin/cursor /usr/local/bin/cursor-agent

.devcontainer/devcontainer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,13 @@
6363
},
6464

6565
// Port forwarding
66-
"forwardPorts": [3000, 8080, 5432, 6379],
66+
"forwardPorts": [3000, 8080, 5432, 6379, 6080],
6767
"portsAttributes": {
6868
"3000": { "label": "Frontend (Vite)", "onAutoForward": "notify" },
6969
"8080": { "label": "Backend (Spring Boot)", "onAutoForward": "notify" },
7070
"5432": { "label": "PostgreSQL", "onAutoForward": "silent" },
71-
"6379": { "label": "Redis", "onAutoForward": "silent" }
71+
"6379": { "label": "Redis", "onAutoForward": "silent" },
72+
"6080": { "label": "VNC (Browser)", "onAutoForward": "notify" }
7273
},
7374

7475
// Lifecycle scripts

.devcontainer/start-vnc.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
# VNC Server Startup Script
3+
# Starts Xvfb, x11vnc, and noVNC for remote browser access
4+
5+
set -e
6+
7+
# Configuration
8+
DISPLAY_NUM=99
9+
VNC_PORT=5900
10+
NOVNC_PORT=6080
11+
RESOLUTION="1400x900x24"
12+
13+
# Check if already running
14+
if pgrep -x "Xvfb" > /dev/null; then
15+
echo "VNC already running"
16+
exit 0
17+
fi
18+
19+
echo "Starting VNC server..."
20+
21+
# Start Xvfb (Virtual Framebuffer)
22+
Xvfb :${DISPLAY_NUM} -screen 0 ${RESOLUTION} &
23+
sleep 2
24+
25+
export DISPLAY=:${DISPLAY_NUM}
26+
27+
# Start x11vnc
28+
x11vnc -display :${DISPLAY_NUM} -forever -nopw -shared -rfbport ${VNC_PORT} &
29+
sleep 2
30+
31+
# Start noVNC (web-based VNC client)
32+
/usr/share/novnc/utils/novnc_proxy --vnc localhost:${VNC_PORT} --listen ${NOVNC_PORT} &
33+
sleep 1
34+
35+
echo "VNC server started!"
36+
echo " - Display: :${DISPLAY_NUM}"
37+
echo " - VNC Port: ${VNC_PORT}"
38+
echo " - noVNC Port: ${NOVNC_PORT}"

0 commit comments

Comments
 (0)