init
This commit is contained in:
138
.devcontainer/start-vnc.sh
Executable file
138
.devcontainer/start-vnc.sh
Executable file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Start a headless X server, a lightweight desktop, x11vnc and noVNC proxy.
|
||||
# Runs as the container user (configured via devcontainer.json remoteUser).
|
||||
|
||||
VNC_PASS=${VNC_PASSWORD:-devpass}
|
||||
VNC_DIR="$HOME/.vnc"
|
||||
mkdir -p "$VNC_DIR"
|
||||
|
||||
if [ ! -f "$VNC_DIR/passwd" ]; then
|
||||
echo "Creating VNC password"
|
||||
x11vnc -storepasswd "$VNC_PASS" "$VNC_DIR/passwd"
|
||||
fi
|
||||
|
||||
# Prefer using an existing X server (host) when available. Set USE_EXISTING_DISPLAY=true
|
||||
# to force using the existing DISPLAY; otherwise, if a host DISPLAY is propagated into the
|
||||
# container (via devcontainer runArgs / mounts), prefer that instead of starting Xvfb.
|
||||
if [ "${USE_EXISTING_DISPLAY:-}" = "true" ] || { [ -n "${DISPLAY:-}" ] && [ -d "/tmp/.X11-unix" ]; }; then
|
||||
echo "Using existing X server on ${DISPLAY:-<unset>} (X11 forwarding to host)"
|
||||
export USE_EXISTING_DISPLAY=true
|
||||
else
|
||||
echo "Prefer Xvfb — starting Xvfb :1"
|
||||
if command -v Xvfb >/dev/null 2>&1; then
|
||||
# Define virtual screen size once; will try to confirm at runtime
|
||||
# using xdpyinfo and fall back to these values if xdpyinfo isn't available.
|
||||
SCREEN_W=1280
|
||||
SCREEN_H=800
|
||||
# Use a slightly taller virtual screen so desktop panels/toolbars
|
||||
# don't cause the noVNC client to show an unexpected area below
|
||||
# the visible display; use variables so we can clip x11vnc to
|
||||
# exactly the same region and avoid framebuffer artifacts.
|
||||
Xvfb :1 -screen 0 "${SCREEN_W}x${SCREEN_H}x24" >/tmp/xvfb.log 2>&1 &
|
||||
export DISPLAY=:1
|
||||
else
|
||||
echo "Warning: Xvfb not available; expecting an X server on DISPLAY"
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "Starting desktop session (xfce)"
|
||||
# startxfce4 backgrounds itself; if not available fall back to openbox
|
||||
if command -v startxfce4 >/dev/null 2>&1; then
|
||||
startxfce4 >/tmp/xfce4.log 2>&1 &
|
||||
else
|
||||
if command -v openbox-session >/dev/null 2>&1; then
|
||||
openbox-session >/tmp/openbox.log 2>&1 &
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "Starting x11vnc on ${DISPLAY:-:1}"
|
||||
if [ "${USE_EXISTING_DISPLAY:-}" != "true" ]; then
|
||||
# Query the actual display size (xdpyinfo) to compute a precise clip region
|
||||
# and avoid sending framebuffer rows outside the visible desktop. Disable
|
||||
# client-side caching which can sometimes produce visual artifacts.
|
||||
GEOM=""
|
||||
if command -v xdpyinfo >/dev/null 2>&1; then
|
||||
GEOM=$(xdpyinfo -display "${DISPLAY:-:1}" 2>/dev/null | awk '/dimensions:/ {print $2}') || true
|
||||
fi
|
||||
if [ -n "$GEOM" ]; then
|
||||
# GEOM looks like WxH (e.g. 1280x800)
|
||||
W=${GEOM%x*}
|
||||
H=${GEOM#*x}
|
||||
else
|
||||
W=${SCREEN_W}
|
||||
H=${SCREEN_H}
|
||||
fi
|
||||
echo "Starting x11vnc with clip ${W}x${H}+0+0 (display ${DISPLAY:-:1})"
|
||||
x11vnc -display "${DISPLAY:-:1}" -rfbauth "$VNC_DIR/passwd" -forever -shared -rfbport 5900 -clip ${W}x${H}+0+0 -bg || true
|
||||
else
|
||||
echo "USE_EXISTING_DISPLAY=true — skipping x11vnc (display forwarded to host)"
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
# Locate noVNC installation. Prefer /opt/noVNC, then workspace/noVNC.
|
||||
NOVNC_DIR=""
|
||||
if [ -d /opt/noVNC ]; then
|
||||
NOVNC_DIR="/opt/noVNC"
|
||||
elif [ -d "$PWD/noVNC" ]; then
|
||||
NOVNC_DIR="$PWD/noVNC"
|
||||
# Ensure it's available under /opt for tools that expect it there
|
||||
if [ ! -e /opt/noVNC ]; then
|
||||
mkdir -p /opt
|
||||
ln -s "$NOVNC_DIR" /opt/noVNC || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start the noVNC proxy only when we are running an internal VNC server on port 5900
|
||||
if [ -n "$NOVNC_DIR" ] && [ "${USE_EXISTING_DISPLAY:-}" != "true" ]; then
|
||||
echo "Found noVNC at $NOVNC_DIR"
|
||||
# If a wrapper exists in the devcontainer, install it into the noVNC web
|
||||
# root so we can set localStorage defaults (e.g. prefer local scaling)
|
||||
WRAPPER="${SCRIPT_DIR:-$(pwd)}/novnc/vnc-wrapper.html"
|
||||
if [ -f "$WRAPPER" ]; then
|
||||
# Backup original vnc.html once and replace with wrapper
|
||||
if [ -f "$NOVNC_DIR/vnc.html" ] && [ ! -f "$NOVNC_DIR/vnc.orig.html" ]; then
|
||||
echo "Backing up original noVNC vnc.html to vnc.orig.html and installing wrapper"
|
||||
cp "$NOVNC_DIR/vnc.html" "$NOVNC_DIR/vnc.orig.html" || true
|
||||
cp "$WRAPPER" "$NOVNC_DIR/vnc.html" || true
|
||||
fi
|
||||
fi
|
||||
echo "Waiting for VNC server on localhost:5900..."
|
||||
ATTEMPTS=0
|
||||
until ss -ltnp | grep -q ':5900' || [ $ATTEMPTS -ge 10 ]; do
|
||||
ATTEMPTS=$((ATTEMPTS+1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if ss -ltnp | grep -q ':5900'; then
|
||||
# If port 6080 is already bound, report the owner and skip starting a new proxy.
|
||||
if ss -ltnp | grep -q ':6080'; then
|
||||
echo "Port 6080 already in use. Current listener:"
|
||||
ss -ltnp | egrep ':6080' || true
|
||||
echo "Skipping starting another noVNC proxy to avoid address-in-use errors."
|
||||
else
|
||||
echo "Starting noVNC proxy on port 6080"
|
||||
# Prefer the bundled novnc_proxy script; pass explicit --web and bind address
|
||||
NOVNC_PROXY="$NOVNC_DIR/utils/novnc_proxy"
|
||||
if [ -x "$NOVNC_PROXY" ]; then
|
||||
nohup "$NOVNC_PROXY" --vnc localhost:5900 --listen 0.0.0.0:6080 --web "$NOVNC_DIR" >/tmp/novnc.log 2>&1 &
|
||||
else
|
||||
nohup python3 "$NOVNC_DIR/utils/novnc_proxy" --vnc localhost:5900 --listen 0.0.0.0:6080 --web "$NOVNC_DIR" >/tmp/novnc.log 2>&1 &
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "VNC server not listening on :5900, skipping noVNC startup. See logs for details."
|
||||
fi
|
||||
else
|
||||
if [ "${USE_EXISTING_DISPLAY:-}" = "true" ]; then
|
||||
echo "Using host X11 forwarding; skipping noVNC/websockify startup."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "VNC service started. Connect to :5900 or open http://<host>:6080/vnc.html"
|
||||
Reference in New Issue
Block a user