The Xvfb readiness loop in entrypoint.sh used xdpyinfo, which isn't in the Playwright base image. On busy hosts the loop fell through before Xvfb was ready, so Chromium launched with no X server and crashed with "Missing X server or \$DISPLAY". Add x11-utils (provides xdpyinfo) and extend the readiness loop to 10 s with explicit logging. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
77 lines
2.4 KiB
Bash
Executable File
77 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Start Xvfb + x11vnc + noVNC so a human can complete Reddit login
|
|
# through the dashboard, then exec the Node bot which drives Chromium
|
|
# on that virtual display.
|
|
set -euo pipefail
|
|
|
|
DISPLAY_NUM="${VNC_DISPLAY_NUM:-99}"
|
|
VNC_PORT="${VNC_PORT:-5900}"
|
|
NOVNC_PORT="${NOVNC_PORT:-6080}"
|
|
GEOMETRY="${SCREEN_GEOMETRY:-1280x800x24}"
|
|
export DISPLAY=":${DISPLAY_NUM}"
|
|
|
|
# noVNC ships under different paths depending on the distro; find the web root once.
|
|
if [ -d /usr/share/novnc ]; then
|
|
NOVNC_WEB_DIR=/usr/share/novnc
|
|
elif [ -d /usr/share/webapps/novnc ]; then
|
|
NOVNC_WEB_DIR=/usr/share/webapps/novnc
|
|
else
|
|
echo "[entrypoint] could not locate noVNC web root" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Make / on the noVNC server land on vnc.html with autoconnect.
|
|
if [ ! -e "${NOVNC_WEB_DIR}/index.html" ] && [ -e "${NOVNC_WEB_DIR}/vnc.html" ]; then
|
|
ln -sf vnc.html "${NOVNC_WEB_DIR}/index.html"
|
|
fi
|
|
|
|
echo "[entrypoint] starting Xvfb on ${DISPLAY} (${GEOMETRY})"
|
|
Xvfb "${DISPLAY}" -screen 0 "${GEOMETRY}" -ac +extension RANDR &
|
|
XVFB_PID=$!
|
|
|
|
# Give Xvfb a moment to come up. Requires x11-utils (xdpyinfo).
|
|
for i in $(seq 1 50); do
|
|
if xdpyinfo -display "${DISPLAY}" >/dev/null 2>&1; then
|
|
echo "[entrypoint] Xvfb is ready after ${i} checks"
|
|
break
|
|
fi
|
|
sleep 0.2
|
|
if [ "${i}" = "50" ]; then
|
|
echo "[entrypoint] WARNING: Xvfb did not respond after 10s" >&2
|
|
fi
|
|
done
|
|
|
|
# Minimal window manager so dialogs and tabs aren't stuck behind the root window.
|
|
if command -v fluxbox >/dev/null 2>&1; then
|
|
fluxbox >/dev/null 2>&1 &
|
|
fi
|
|
|
|
VNC_ARGS=(-display "${DISPLAY}" -forever -shared -rfbport "${VNC_PORT}" -nopw_warn)
|
|
if [ -n "${VNC_PASSWORD:-}" ]; then
|
|
mkdir -p /root/.vnc
|
|
x11vnc -storepasswd "${VNC_PASSWORD}" /root/.vnc/passwd >/dev/null
|
|
VNC_ARGS+=(-rfbauth /root/.vnc/passwd)
|
|
echo "[entrypoint] x11vnc starting with password auth"
|
|
else
|
|
VNC_ARGS+=(-nopw)
|
|
echo "[entrypoint] WARNING: VNC_PASSWORD not set — VNC has no auth"
|
|
fi
|
|
|
|
x11vnc "${VNC_ARGS[@]}" >/var/log/x11vnc.log 2>&1 &
|
|
X11VNC_PID=$!
|
|
|
|
echo "[entrypoint] starting noVNC (websockify) on :${NOVNC_PORT}"
|
|
websockify --web "${NOVNC_WEB_DIR}" "${NOVNC_PORT}" "localhost:${VNC_PORT}" \
|
|
>/var/log/websockify.log 2>&1 &
|
|
NOVNC_PID=$!
|
|
|
|
cleanup() {
|
|
echo "[entrypoint] shutting down"
|
|
kill "${NOVNC_PID}" "${X11VNC_PID}" "${XVFB_PID}" 2>/dev/null || true
|
|
wait || true
|
|
}
|
|
trap cleanup TERM INT EXIT
|
|
|
|
echo "[entrypoint] launching bot"
|
|
exec node dist/index.js
|