FROM node:22-slim ENV NODE_ENV=production \ PORT=7860 \ HOSTNAME=0.0.0.0 \ NEXT_TELEMETRY_DISABLED=1 RUN apt-get update && apt-get install -y --no-install-recommends \ python3 python3-pip curl procps build-essential ca-certificates \ && rm -rf /var/lib/apt/lists/* RUN pip3 install --break-system-packages --no-cache-dir huggingface_hub # Install OmniRoute & runtime dependencies RUN npm install -g omniroute@3.8.0 --prefer-online --no-audit --no-fund \ && mkdir -p /root/.omniroute/runtime \ && cd /root/.omniroute/runtime \ && npm install sql.js@1.14.1 better-sqlite3@12.10.0 --no-audit --no-fund --prefer-online WORKDIR /app # Script Sync RUN cat > /app/sync.py <<'PY' import os import tarfile import time import sys from pathlib import Path from huggingface_hub import HfApi, hf_hub_download REPO_ID = os.environ.get("DATASET_REPO") TOKEN = os.environ.get("HF_TOKEN") BACKUP_FILE = "/tmp/omniroute_backup.tar.gz" DATA_DIR = Path("/root/.omniroute") def safe_extract(tar, path): base = Path(path).resolve() for member in tar.getmembers(): target = (base / member.name).resolve() if not str(target).startswith(str(base)): raise RuntimeError(f"unsafe tar member: {member.name}") tar.extractall(path) def upload(): if not REPO_ID or not TOKEN: return if not DATA_DIR.exists(): return try: with tarfile.open(BACKUP_FILE, "w:gz") as tar: tar.add(str(DATA_DIR), arcname=".omniroute") HfApi(token=TOKEN).upload_file( path_or_fileobj=BACKUP_FILE, path_in_repo="omniroute_backup.tar.gz", repo_id=REPO_ID, repo_type="dataset", ) print(">>> [Sync] Backup sukses: " + time.strftime("%Y-%m-%d %H:%M:%S"), flush=True) except Exception as e: print(">>> [Sync] Backup gagal: " + str(e), flush=True) def download(): if not REPO_ID or not TOKEN: return try: print(">>> [Sync] Restore dari Dataset...", flush=True) path = hf_hub_download(repo_id=REPO_ID, filename="omniroute_backup.tar.gz", repo_type="dataset", token=TOKEN) with tarfile.open(path, "r:gz") as tar: safe_extract(tar, "/root") print(">>> [Sync] Restore sukses", flush=True) except Exception as e: print(">>> [Sync] Skip restore: " + str(e), flush=True) if __name__ == "__main__": if len(sys.argv) > 1 and sys.argv[1] == "upload": upload() elif len(sys.argv) > 1 and sys.argv[1] == "download": download() PY # Entrypoint script RUN cat > /app/run.sh <<'SH' #!/bin/bash set -euo pipefail mkdir -p /root/.omniroute/runtime echo '=== 1. Restore Data ===' python3 /app/sync.py download echo '=== 2. Cron Backup (10m) ===' (while true; do sleep 600; python3 /app/sync.py upload; done) & echo '=== 3. Start OmniRoute ===' export PORT=7860 # OmniRoute 3.8.0 CLI flags fix: exec omniroute serve --port 7860 --no-open --log SH RUN chmod +x /app/run.sh EXPOSE 7860 CMD ["/bin/bash", "/app/run.sh"]