build-and-push failed on the last deploy: chromium-headless-shell's single ~181MB binary can't be split across Docker layers the way this project's pip/npm installs were (those are many independently- installable smaller packages; this is one file), and confirmed-failed to push past the registry's per-layer size limit. Moves the `playwright install chromium-headless-shell` step from the Dockerfile to start.sh, caching into PLAYWRIGHT_BROWSERS_PATH on the /data volume -- only the very first boot on a fresh volume downloads it, every boot after that is a no-op check. The image itself no longer grows by ~262MB, so nothing new gets pushed to the registry at all.
37 lines
1.8 KiB
Bash
Executable File
37 lines
1.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# Starts render-service/ (whiteboard frame mode's Excalidraw-to-PNG
|
|
# sidecar, see its own README) in the background, bound to 127.0.0.1 --
|
|
# reachable from this container's Python process, never from outside it.
|
|
# Then execs uvicorn as the foreground/PID 1 process so it receives
|
|
# Docker's stop signal directly.
|
|
#
|
|
# Before either: fetch headless Chromium (app/html_render.py, the
|
|
# weather widget's opt-in "modern" render style) into
|
|
# PLAYWRIGHT_BROWSERS_PATH (set in the Dockerfile to a path on the /data
|
|
# volume) if it isn't already cached there -- see the Dockerfile's own
|
|
# comment for why this happens at startup instead of build time. Only
|
|
# the very first boot on a fresh volume actually downloads anything;
|
|
# every boot after that is a no-op ls check.
|
|
if [ -z "$(ls -A "$PLAYWRIGHT_BROWSERS_PATH" 2>/dev/null)" ]; then
|
|
echo "Fetching headless Chromium into $PLAYWRIGHT_BROWSERS_PATH (first boot on this volume)..." >&2
|
|
playwright install chromium-headless-shell
|
|
fi
|
|
#
|
|
# Wrapped in a restart loop, not a bare `node ... &`: a bare background
|
|
# process that crashes stays dead for good, with nothing to bring it
|
|
# back -- turning any single render crash (a not-yet-found jsdom/
|
|
# Excalidraw edge case, say) into a silent, permanent whiteboard outage
|
|
# that looks exactly like "stuck showing stale content forever" from the
|
|
# outside, since routers/common.py's get_or_refresh_whiteboard falls
|
|
# back to the last good cached image on every failed refresh rather than
|
|
# going blank. The 2s sleep just avoids a hot-crash-loop pegging a core
|
|
# if something's wrong at every single startup.
|
|
(
|
|
while true; do
|
|
node ./render-service/server.js
|
|
echo "whiteboard render sidecar exited (code $?) -- restarting in 2s" >&2
|
|
sleep 2
|
|
done
|
|
) &
|
|
exec uvicorn app.main:app --host 0.0.0.0 --port 8420
|