fix: discover sitespeed.js path at build time, export via /sitespeed_env

sitespeed.io is not on PATH in the container -- the base image uses a
full absolute path for its ENTRYPOINT. We now run 'find' during the
Docker build, write the path to /sitespeed_env, and source it in
start.sh so SITESPEED_BIN is set before node app.js starts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 20:09:29 +02:00
parent 54a83f5585
commit ad5881302e
3 changed files with 25 additions and 12 deletions

View File

@@ -19,6 +19,13 @@ COPY . .
RUN chmod +x /app/start.sh RUN chmod +x /app/start.sh
# Locate sitespeed.js at build time and write the path to /sitespeed_env.
# The base image sets sitespeed.io as ENTRYPOINT via a full path, so it is
# not on $PATH. We find it once here so start.sh can export it at runtime.
RUN SITESPEED_JS=$(find / -name 'sitespeed.js' -path '*/bin/*' 2>/dev/null | head -1); \
echo "Build-time sitespeed.js found at: $SITESPEED_JS"; \
echo "export SITESPEED_BIN=$SITESPEED_JS" > /sitespeed_env
# Create persistent directories # Create persistent directories
RUN mkdir -p /data/reports RUN mkdir -p /data/reports

View File

@@ -6,10 +6,6 @@ import { existsSync } from 'fs';
const __dirname = dirname(fileURLToPath(import.meta.url)); const __dirname = dirname(fileURLToPath(import.meta.url));
const LOCAL_BIN = join(__dirname, '..', 'sitespeed.io', 'bin', 'sitespeed.js'); const LOCAL_BIN = join(__dirname, '..', 'sitespeed.io', 'bin', 'sitespeed.js');
// Shell-escape a single argument (single-quote wrapping)
function q(arg) {
return `'${String(arg).replace(/'/g, "'\\''")}'`;
}
export function runTest(job, onLine) { export function runTest(job, onLine) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@@ -40,12 +36,17 @@ export function runTest(job, onLine) {
let child; let child;
if (isDocker) { if (isDocker) {
// In Docker, sitespeed.io is on PATH but execSync can't see it from Node's // SITESPEED_BIN is set by start.sh from the build-time path discovery
// limited environment. Use 'sh -c' so the full shell PATH is used. const bin = process.env.SITESPEED_BIN;
const shellCmd = ['sitespeed.io', ...sitespeedArgs].map(q).join(' '); if (!bin) {
onLine(`[runner] sh -c ${shellCmd.slice(0, 120)}...`); return reject(new Error(
'SITESPEED_BIN is not set. The Docker build may not have found sitespeed.js.\n' +
'Check build logs for "Build-time sitespeed.js found at:"'
));
}
onLine(`[runner] node ${bin}`);
onLine(`[runner] DISPLAY=${env.DISPLAY}`); onLine(`[runner] DISPLAY=${env.DISPLAY}`);
child = spawn('sh', ['-c', shellCmd], { cwd: __dirname, env }); child = spawn('node', [bin, ...sitespeedArgs], { cwd: __dirname, env });
} else { } else {
if (!existsSync(LOCAL_BIN)) { if (!existsSync(LOCAL_BIN)) {
return reject(new Error( return reject(new Error(

View File

@@ -1,12 +1,17 @@
#!/bin/bash #!/bin/bash
set -e set -e
# Start virtual framebuffer so Chrome/Firefox have a display to render into. # Load the sitespeed.io binary path discovered at build time
# This is what the base sitespeedio/sitespeed.io image's entrypoint does. if [ -f /sitespeed_env ]; then
source /sitespeed_env
fi
echo "[start.sh] SITESPEED_BIN=${SITESPEED_BIN:-NOT FOUND}"
# Start virtual framebuffer so Chrome/Firefox have a display to render into
Xvfb :99 -ac -screen 0 1920x1080x24 +extension RANDR & Xvfb :99 -ac -screen 0 1920x1080x24 +extension RANDR &
export DISPLAY=:99 export DISPLAY=:99
# Give Xvfb a moment to initialise
sleep 1 sleep 1
exec node /app/app.js exec node /app/app.js