Clear the stale Chrome singleton lock at browser boot

A Chrome killed uncleanly leaves SingletonLock in the chrome-profile
volume, naming the hostname and pid that took it. Both change when the
container is rebuilt, so the next Chrome reads it as "another computer
holds this profile" and exits at startup — permanently, since the volume
outlives every recreate.

The only symptom was a bare connection reset at 9222: socat accepts,
start_browser fires, Chrome dies, wait_for_browser bails on browser_alive
and the helper closes the socket. Chrome's stderr went to /dev/null and
the give-up path logged nothing, so neither docker logs nor the client
could tell a dead browser from a dead network — which is most of why this
cost an afternoon. Both are now on the container's stderr.

Clearing the lock at boot is safe because container_name pins the volume
to one container: nothing can hold the profile when that line runs. A
lock left mid-lifetime is self-healing (same hostname, dead pid), so boot
is the whole exposure.
This commit is contained in:
2026-08-10 19:10:43 +07:00
parent b22ae82897
commit 6489f97686
+14 -1
View File
@@ -77,7 +77,7 @@ start_browser() {
--no-first-run \ --no-first-run \
--no-default-browser-check \ --no-default-browser-check \
--disable-gpu \ --disable-gpu \
about:blank >/dev/null 2>&1 & about:blank >/dev/null &
printf '%s\n' "$!" >"$pid_file" printf '%s\n' "$!" >"$pid_file"
} }
@@ -140,6 +140,9 @@ connection() {
result=$? result=$?
fi fi
else else
# The client only ever sees a bare connection reset here, so this is
# the sole record that the browser, not the network, was the problem.
echo "browser did not come up; dropping connection" >&2
result=1 result=1
fi fi
finish_connection finish_connection
@@ -174,6 +177,16 @@ for marker in "$connections_dir"/*; do
done done
rm -f "$pid_file" "$last_use_file" rm -f "$pid_file" "$last_use_file"
# Chrome's singleton lock names the hostname and pid that took it, and a
# container rebuild changes both — so a Chrome killed uncleanly (OOM, docker
# kill) leaves a lock the next container reads as "another computer holds this
# profile" and refuses to start behind, permanently, with the only symptom a
# bare connection reset at 9222. Clearing it here is safe precisely because
# container_name pins this volume to one container: nothing can be holding the
# profile at the moment this line runs. The lock is process state; the
# clearance cookies it sits beside are not, and are left alone.
rm -f "$profile"/Singleton*
# Chrome binds DevTools to loopback and silently ignores # Chrome binds DevTools to loopback and silently ignores
# --remote-debugging-address. socat remains the network front-end, but each # --remote-debugging-address. socat remains the network front-end, but each
# accepted connection now starts a browser on demand and is tracked by a # accepted connection now starts a browser on demand and is tracked by a