Download sync-entrypoint.sh from Really-amin/Datasourceforcryptocurrency-6: direct link, hf CLI and curl.
- Browser
- Download file 5.21 kB
-
https://huggingface.co/spaces/Really-amin/Datasourceforcryptocurrency-6/resolve/main/sync-entrypoint.sh
- Command line
-
hf download hf://spaces/Really-amin/Datasourceforcryptocurrency-6/sync-entrypoint.sh
-
curl -L -o sync-entrypoint.sh https://huggingface.co/spaces/Really-amin/Datasourceforcryptocurrency-6/resolve/main/sync-entrypoint.sh
5.21 kB
| set -e | |
| # ββ Secrets βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Set these as HF Secrets in Space Settings β Variables and secrets. | |
| # If unset, random values are generated β auth breaks on every restart! | |
| if [ -z "$JWT_SECRET" ]; then | |
| echo "[WARN] JWT_SECRET not set β generating ephemeral value. Set it as a HF Secret." | |
| export JWT_SECRET="$(openssl rand -base64 48)" | |
| fi | |
| if [ -z "$API_KEY_SECRET" ]; then | |
| echo "[WARN] API_KEY_SECRET not set β generating ephemeral value. Set it as a HF Secret." | |
| export API_KEY_SECRET="$(openssl rand -hex 32)" | |
| fi | |
| if [ -z "$OMNIROUTE_WS_BRIDGE_SECRET" ]; then | |
| echo "[WARN] OMNIROUTE_WS_BRIDGE_SECRET not set β generating ephemeral value." | |
| export OMNIROUTE_WS_BRIDGE_SECRET="$(openssl rand -hex 32)" | |
| fi | |
| # ββ Core config βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export PORT="${PORT:-7860}" | |
| export HOSTNAME="0.0.0.0" | |
| export INITIAL_PASSWORD="${INITIAL_PASSWORD:-omniroute}" | |
| export DATA_DIR="${DATA_DIR:-/app/data}" | |
| export AUTH_COOKIE_SECURE="${AUTH_COOKIE_SECURE:-false}" | |
| export NODE_ENV="${NODE_ENV:-production}" | |
| export STORAGE_DRIVER="${STORAGE_DRIVER:-sqlite}" | |
| # ββ Public URL ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| if [ -n "$SPACE_HOST" ]; then | |
| export NEXT_PUBLIC_BASE_URL="https://${SPACE_HOST}" | |
| export BASE_URL="https://${SPACE_HOST}" | |
| else | |
| export NEXT_PUBLIC_BASE_URL="${NEXT_PUBLIC_BASE_URL:-http://0.0.0.0:${PORT}}" | |
| export BASE_URL="${BASE_URL:-${NEXT_PUBLIC_BASE_URL}}" | |
| fi | |
| # ββ Storage dir must exist before restore βββββββββββββββββββββββββββββββββββββ | |
| mkdir -p "$DATA_DIR" | |
| # ββ HF Dataset persistence (Node, zero-dependency) ββββββββββββββββββββββββββββ | |
| # Set HF_TOKEN + HF_STATE_DATASET as HF Secrets to persist the DB across | |
| # restarts and rebuilds. Unlike the old python3/huggingface_hub block, hf-sync | |
| # needs nothing beyond the Node runtime that already ships in this image, it | |
| # pulls a WAL-consistent snapshot via OmniRoute's own export API, and it uploads | |
| # on an interval AND on shutdown (SIGTERM) so a restart can't drop config. | |
| if [ -n "$HF_TOKEN" ] && [ -n "$HF_STATE_DATASET" ]; then | |
| echo "[sync] Restoring state from HF dataset: $HF_STATE_DATASET" | |
| node /app/hf-sync.mjs restore || echo "[sync] restore reported an error (continuing with local/fresh DB)" | |
| else | |
| echo "[sync] HF persistence disabled" | |
| echo "[sync] Set HF_TOKEN and HF_STATE_DATASET to enable persistence" | |
| fi | |
| echo "================================================" | |
| echo " OmniRoute starting on port $PORT" | |
| echo " Dashboard: ${NEXT_PUBLIC_BASE_URL}" | |
| echo " Data dir: $DATA_DIR" | |
| echo "================================================" | |
| # ββ Run the app as a child so we can snapshot on shutdown βββββββββββββββββββββ | |
| # HF Spaces delivers SIGTERM on restart/rebuild AND when a free Space is put to | |
| # sleep. `exec node β¦` would replace this shell and make a shutdown snapshot | |
| # impossible, so we background the app, trap the signal, take one final upload, | |
| # then forward the signal on. | |
| # | |
| # Ordering matters and is deliberate: we snapshot the DB via OmniRoute's own | |
| # export API *while the app is still alive*, and only THEN stop the app. The | |
| # final snapshot is bounded by `timeout` (and a low per-request timeout) so on | |
| # slow cpu-basic hardware it aborts cleanly β leaving the dataset on the last | |
| # good commit β rather than being frozen mid-upload when SIGKILL lands. The | |
| # periodic daemon is the real safety net; this is best-effort on top. | |
| APP_PID="" | |
| SHUTDOWN_BUDGET="${HF_SYNC_SHUTDOWN_SECONDS:-8}" | |
| shutdown() { | |
| echo "[sync] shutdown signal received" | |
| if [ -n "$HF_TOKEN" ] && [ -n "$HF_STATE_DATASET" ]; then | |
| echo "[sync] taking final snapshot before exit (budget ${SHUTDOWN_BUDGET}s)" | |
| HF_SYNC_HTTP_TIMEOUT_MS=$(( (SHUTDOWN_BUDGET - 1) * 1000 )) \ | |
| timeout "${SHUTDOWN_BUDGET}s" node /app/hf-sync.mjs snapshot \ | |
| || echo "[sync] final snapshot skipped/failed (dataset stays on last good commit)" | |
| fi | |
| if [ -n "$APP_PID" ]; then kill -TERM "$APP_PID" 2>/dev/null || true; wait "$APP_PID" 2>/dev/null || true; fi | |
| exit 0 | |
| } | |
| trap shutdown TERM INT | |
| # Periodic snapshotter (no-ops immediately if persistence is disabled). | |
| node /app/hf-sync.mjs daemon & | |
| SYNC_PID=$! | |
| node dev/run-standalone.mjs & | |
| APP_PID=$! | |
| # `wait` returns when the trap fires; loop so we keep waiting until the app | |
| # actually exits rather than returning on the first delivered signal. | |
| while kill -0 "$APP_PID" 2>/dev/null; do | |
| wait "$APP_PID" && break | |
| done | |
| EXIT_CODE=$? | |
| kill -TERM "$SYNC_PID" 2>/dev/null || true | |
| echo "[sync] app exited with code $EXIT_CODE" | |
| exit $EXIT_CODE | |