Split monolithic chat service into modular structure with Matrix client support, extract web server into per-resource route modules, introduce bootstrap/main-loop separation, and add comprehensive vitest coverage across services, repositories, and utilities. Adds project docs and CLAUDE.md agent instructions.
71 lines
2.2 KiB
Bash
Executable File
71 lines
2.2 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.
|
|
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
|
if xdpyinfo -display "${DISPLAY}" >/dev/null 2>&1; then break; fi
|
|
sleep 0.2
|
|
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
|