diff --git a/Dockerfile b/Dockerfile index 0ccb968..44dd40d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,6 +17,8 @@ RUN npm install --omit=dev COPY . . +RUN chmod +x /app/start.sh + # Create persistent directories RUN mkdir -p /data/reports @@ -33,8 +35,6 @@ ENV PORT=3132 \ EXPOSE 3132 -# Override the base image's ENTRYPOINT (which is "sitespeed.io") so that -# Docker doesn't prepend it to our CMD, causing sitespeed.io to treat -# "node" as a URL to test. -ENTRYPOINT ["node"] -CMD ["app.js"] +# start.sh boots Xvfb (virtual display for Chrome/Firefox) then runs the app. +# This mirrors what the base image's own entrypoint does. +ENTRYPOINT ["/app/start.sh"] diff --git a/runner.js b/runner.js index 57d1ac1..0296f2a 100644 --- a/runner.js +++ b/runner.js @@ -22,17 +22,18 @@ export function runTest(job, onLine) { '--sustainable.enable', '--axe.enable', '--coach', - '--headless', ]; if (job.mobile) { args.push('--mobile'); } - // In Docker we need --xvfb false and --browsertime.chrome.args=no-sandbox + // Chrome needs these flags when running inside Docker if (process.env.IN_DOCKER) { args.push('--browsertime.chrome.args', 'no-sandbox'); args.push('--browsertime.chrome.args', 'disable-dev-shm-usage'); + // Disable GPU compositing — not needed in Xvfb and can cause crashes + args.push('--browsertime.chrome.args', 'disable-gpu'); } onLine(`[runner] Starting: node ${args.slice(0, 3).join(' ')} ...`); diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..696dac1 --- /dev/null +++ b/start.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +# Start virtual framebuffer so Chrome/Firefox have a display to render into. +# This is what the base sitespeedio/sitespeed.io image's entrypoint does. +Xvfb :99 -ac -screen 0 1920x1080x24 +extension RANDR & +export DISPLAY=:99 + +# Give Xvfb a moment to initialise +sleep 1 + +exec node /app/app.js