9router / Dockerfile
otnansirk's picture
Update Dockerfile
f65541c verified
Raw
History Blame Contribute Delete
3.44 kB
FROM decolua/9router:latest
# 1. Switch to root to install system packages
USER root
# 2. Install Python for the backup script
RUN apk add --no-cache python3 py3-pip tar \
&& pip3 install --break-system-packages --no-cache-dir huggingface_hub
WORKDIR /app
# 3. Create the Python sync script
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/9router_backup.tar.gz"
DATA_DIR = Path("/app/data")
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:
print(">>> [Sync] DATASET_REPO or HF_TOKEN not configured. Skipping backup.")
return
if not DATA_DIR.exists():
print(">>> [Sync] Data directory does not exist. Skipping backup.")
return
try:
with tarfile.open(BACKUP_FILE, "w:gz") as tar:
# We pack the /app/data folder as 'data'
tar.add(str(DATA_DIR), arcname="data")
HfApi(token=TOKEN).upload_file(
path_or_fileobj=BACKUP_FILE,
path_in_repo="9router_backup.tar.gz",
repo_id=REPO_ID,
repo_type="dataset",
)
print(f">>> [Sync] Backup successful: {time.strftime('%Y-%m-%d %H:%M:%S')}", flush=True)
except Exception as e:
print(f">>> [Sync] Backup failed: {e}", flush=True)
def download():
if not REPO_ID or not TOKEN:
print(">>> [Sync] DATASET_REPO or HF_TOKEN not configured. Skipping restore.")
return
try:
print(">>> [Sync] Downloading data from Dataset...", flush=True)
path = hf_hub_download(
repo_id=REPO_ID,
filename="9router_backup.tar.gz",
repo_type="dataset",
token=TOKEN,
)
with tarfile.open(path, "r:gz") as tar:
# Extracting into /app will perfectly place it at /app/data
safe_extract(tar, "/app")
print(">>> [Sync] Data restore successful.", flush=True)
except Exception as e:
print(f">>> [Sync] Skipping restore (might be first run): {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
# 4. Create the startup shell script
RUN cat > /app/run.sh <<'SH'
#!/bin/sh
set -e
echo '=== 0. Resetting Local Data ==='
mkdir -p /app/data
echo '=== 1. Restoring Data ==='
python3 /app/sync.py download
echo '=== 2. Starting Scheduled Backup (Every 10 minutes) ==='
(while true; do sleep 600; python3 /app/sync.py upload; done) &
echo '=== 3. Starting 9router ==='
export PORT=7860
export HOSTNAME=0.0.0.0
export DATA_DIR=/app/data
export NEXT_PUBLIC_BASE_URL="https://${SPACE_HOST:-otnansirk-9router.hf.space}"
echo '=== Checking 9router files ==='
pwd
ls -la
node -e "console.log(require('./package.json').version)" || true
cat package.json | grep version || true
echo '=== 3. Starting 9router ==='
exec node server.js
SH
RUN chmod +x /app/run.sh
EXPOSE 7860
CMD ["/bin/sh", "/app/run.sh"]