selfapi-v2 / start_hf.sh
akashyadav758
Wipe Chrome session-restore state on boot (stop stale tab resurrection)
b0a3b97
Raw
History Blame Contribute Delete
8.63 kB
#!/bin/bash
# Graceful Shutdown Handler
cleanup() {
echo "πŸ›‘ Shutting down..."
pkill -TERM -f chrome-linux64 2>/dev/null || true
sleep 5
# Snapshot the profile (cookies/logins) to Postgres after Chrome has closed
# its files, so the next boot restores a consistent login state.
if [ -n "$DATABASE_URL" ]; then
echo "πŸ’Ύ Backing up Chrome profile to Postgres..."
/opt/profilesync/profilesync backup || echo "⚠️ Backup failed"
fi
exit 0
}
trap cleanup SIGTERM SIGINT
echo "πŸš€ Starting Chrome Headless Boot Sequence on Hugging Face Spaces..."
# 0. Restore Chrome profile from Postgres snapshot (survives HF restart/rebuild).
# DATABASE_URL is a Space secret β€” never hardcode the credential here.
if [ -n "$DATABASE_URL" ]; then
echo "πŸ“₯ Restoring Chrome profile from Postgres..."
/opt/profilesync/profilesync restore || echo "⚠️ Restore skipped/failed (first run?)"
fi
# 1. Structure Detection & Fix
if [ -d "/home/chrome/data/data/Default" ]; then
echo "⚠️ Nested structure detected. Fixing..."
mv /home/chrome/data/data/* /home/chrome/data/ 2>/dev/null || true
rmdir /home/chrome/data/data 2>/dev/null || true
fi
# 2. Deep Junk Cleanup (80% bloat removal)
echo "🧹 Performing Deep Junk Cleanup..."
rm -rf /home/chrome/data/Default/Cache \
/home/chrome/data/Default/Code\ Cache \
/home/chrome/data/Default/GPUCache \
/home/chrome/data/Default/DawnGraphiteCache \
/home/chrome/data/Default/DawnWebGPUCache \
/home/chrome/data/Default/ShaderCache \
/home/chrome/data/Default/GrShaderCache \
/home/chrome/data/Default/Service\ Worker/CacheStorage \
/home/chrome/data/Default/History \
/home/chrome/data/Default/Favicons \
/home/chrome/data/Default/Top\ Sites \
/home/chrome/data/Default/Visited\ Links \
/home/chrome/data/Default/Network\ Action\ Predictor \
/home/chrome/data/Default/Network\ Persistent\ State 2>/dev/null || true
rm -rf /home/chrome/data/component_crx_cache \
/home/chrome/data/optimization_guide_model_store \
/home/chrome/data/WasmTtsEngine \
/home/chrome/data/OnDeviceHeadSuggestModel \
/home/chrome/data/hyphen-data \
/home/chrome/data/ZxcvbnData \
/home/chrome/data/SafetyTips \
/home/chrome/data/Safe\ Browsing* \
/home/chrome/data/BrowserMetrics* \
/home/chrome/data/Crashpad \
/home/chrome/data/GrShaderCache \
/home/chrome/data/ShaderCache \
/home/chrome/data/GraphiteDawnCache 2>/dev/null || true
# 3. Singleton/Lock removal
echo "πŸ”“ Removing lock files..."
find /home/chrome -name "Singleton*" -exec rm -f {} +
rm -f /home/chrome/data/Default/LOCK /home/chrome/data/Default/LOG.old 2>/dev/null || true
# 3b. Session-restore wipe. The persisted profile saves the last set of open tabs
# (Sessions/, Current/Last Tabs, Current/Last Session). On boot Chrome restores
# them β€” which resurrects stale tabs (e.g. the removed Flow tab) regardless of the
# command-line URL. Deleting these makes Chrome open ONLY the launch URL; the
# gpt/gemini extensions then open their own service tabs. Cookies/logins live in
# separate files (Cookies, Login Data, Local Storage) and are untouched.
echo "🧹 Wiping saved session/tab restore state..."
rm -rf /home/chrome/data/Default/Sessions 2>/dev/null || true
rm -f /home/chrome/data/Default/Current\ Tabs \
/home/chrome/data/Default/Last\ Tabs \
/home/chrome/data/Default/Current\ Session \
/home/chrome/data/Default/Last\ Session 2>/dev/null || true
# 4. Preferences Injection (Developer Mode & Crash Fix)
python3 -c "
import json, os
pref_path = '/home/chrome/data/Default/Preferences'
os.makedirs(os.path.dirname(pref_path), exist_ok=True)
data = {}
if os.path.exists(pref_path):
try:
with open(pref_path, 'r') as f:
data = json.load(f)
except:
pass
# Enable Developer Mode
if 'extensions' not in data:
data['extensions'] = {}
if 'ui' not in data['extensions']:
data['extensions']['ui'] = {}
data['extensions']['ui']['developer_mode'] = True
# Prevent Restore Popup
if 'profile' not in data:
data['profile'] = {}
data['profile']['exit_type'] = 'Normal'
with open(pref_path, 'w') as f:
json.dump(data, f)
" 2>/dev/null || true
# 5. Start Go Monitor Server
echo "πŸš€ Starting 3-tab Monitor Server..."
touch /home/chrome/chrome.log
/opt/monitor3/monitor > /home/chrome/monitor.log 2>&1 &
# 6. Start CDP Proxy
echo "πŸ”Œ Starting CDP Proxy..."
socat TCP-LISTEN:9223,fork,bind=0.0.0.0 TCP:127.0.0.1:9222 &
# 6a. Start the backend API servers on localhost. The monitor doubles as a
# gateway and fronts them on :3001 (/gpt, /gemini). Each logs separately
# and runs in the background so a crash never blocks the boot.
echo "🧩 Starting backend API servers (gpt / gemini)..."
( cd /opt/chatgpt && ./agent >> /home/chrome/chatgpt.log 2>&1 & )
( cd /opt/gemini-srv && WS_PORT=9226 PORT=8000 ./free-gemini-api >> /home/chrome/gemini.log 2>&1 & )
# 6b. Periodic profile backup (safety net if HF kills the container without a clean
# SIGTERM). Best-effort every 5 minutes; the shutdown trap does the final one.
if [ -n "$DATABASE_URL" ]; then
echo "πŸ—„οΈ Profile auto-backup every 5 min enabled."
( while sleep 300; do /opt/profilesync/profilesync backup >/dev/null 2>&1 || true; done ) &
fi
# 6c. Provide a valid per-user runtime dir. Chrome's mojo/IPC layer and each MV3
# extension service worker need this; without it Chrome logs
# "XDG_RUNTIME_DIR is invalid or not set" and the extension service workers
# intermittently fail to spawn (DidStartWorkerFail) β†’ the gpt/gemini
# extensions never connect. Purely additive: just creates a dir and exports it.
export XDG_RUNTIME_DIR=/tmp/runtime-chrome
mkdir -p "$XDG_RUNTIME_DIR" && chmod 700 "$XDG_RUNTIME_DIR"
# 7. Launch Chrome Headless
# NOTE: do NOT add --renderer-process-limit=1 / --process-per-site / --no-zygote here.
# Each extension runs an MV3 service worker (its own renderer) and the chat
# pipeline injects via chrome.scripting.executeScript into the service tab. Capping renderers
# starves those workers β€” they fail to start (DidStartWorkerFail) so the extension never
# connects, and when one does start, executeScript hangs β†’ the /gpt /gemini APIs
# hang forever. HF cpu-basic has 16 GB (we use ~1–2 GB), so the memory "savings" weren't
# needed and broke the extensions. Keep Chrome multi-process.
echo "✨ Launching Chrome Headless..."
/opt/chrome-linux64/chrome \
--headless=new \
--no-sandbox \
--disable-setuid-sandbox \
--disable-infobars \
--disable-blink-features=AutomationControlled \
--excludeSwitches=enable-automation \
--use-fake-ui-for-media-stream \
--use-fake-device-for-media-stream \
--use-mock-keychain \
--password-store=basic \
--window-size=980,1070 \
--user-agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36' \
--disable-gpu \
--disable-software-rasterizer \
--disable-gpu-compositing \
--disable-breakpad \
--disable-crash-reporter \
--mute-audio \
--in-process-gpu \
--disable-dev-shm-usage \
--font-render-hinting=none \
--disable-font-subpixel-positioning \
--force-color-profile=srgb \
--remote-debugging-port=9222 \
--remote-debugging-address=127.0.0.1 \
--remote-allow-origins='*' \
--user-data-dir=/home/chrome/data \
--disable-background-networking \
--disable-sync \
--no-first-run \
--disable-default-apps \
--disable-background-timer-throttling \
--disable-renderer-backgrounding \
--disable-backgrounding-occluded-windows \
--load-extension=/opt/gpt-extension,/opt/gemini-extension \
--disable-extensions-except=/opt/gpt-extension,/opt/gemini-extension \
--disable-translate \
--memory-pressure-off \
--disable-client-side-phishing-detection \
--disable-component-update \
--disable-domain-reliability \
--disable-hang-monitor \
--disable-ipc-flooding-protection \
--disable-popup-blocking \
--disable-prompt-on-repost \
--disable-cookie-encryption \
--force-dark-mode \
--udp-force-randomized-port \
--disable-partial-raster \
--disable-features=TranslateUI,PaintHolding,IsolateOrigins,site-per-process \
--enable-features=NetworkService,NetworkServiceInProcess \
--disable-site-isolation-trials \
--js-flags="--max-old-space-size=512" \
--metrics-recording-only \
'https://chatgpt.com/' >> /home/chrome/chrome.log 2>&1