File size: 3,333 Bytes
c1f75f8 2a70d44 9c54098 38b3f23 9c54098 c1f75f8 9c54098 c1f75f8 9c54098 c1f75f8 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 2a70d44 9c54098 c1f75f8 9c54098 c1f75f8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | FROM hectorqin/reader:openj9-latest
USER root
# socat: 端口转发
# python3/pip + huggingface_hub: 上传/下载 dataset 文件
RUN apt-get update && apt-get install -y socat python3 python3-pip && \
pip3 install --no-cache-dir huggingface_hub
RUN mkdir -p /storage /app/bin/logs && chmod -R 777 /storage /app/bin/logs
EXPOSE 7860
RUN cat > /app/run.sh <<'SH'
#!/bin/sh
set -u
: "${BACKUP_REPO:=yourname/reader-backup}"
: "${BACKUP_FILENAME:=reader_backup_min.tgz}"
: "${BACKUP_INTERVAL:=1800}" # 30 分钟一次,别太频繁
: "${STORAGE_DIR:=/storage}"
echo "==== Reader minimal backup via HF Dataset ===="
echo "BACKUP_REPO=$BACKUP_REPO"
echo "BACKUP_FILENAME=$BACKUP_FILENAME"
echo "BACKUP_INTERVAL=$BACKUP_INTERVAL"
echo "STORAGE_DIR=$STORAGE_DIR"
mkdir -p "$STORAGE_DIR"
chmod -R 777 "$STORAGE_DIR" || true
# 1) 启动时:从 dataset 恢复(如果存在)
echo "[1/3] Try restore from dataset..."
RESTORE_PATH="$(python3 - <<PY
import os, sys
from huggingface_hub import hf_hub_download
repo=os.environ.get("BACKUP_REPO")
token=os.environ.get("HF_TOKEN")
fname=os.environ.get("BACKUP_FILENAME","reader_backup_min.tgz")
try:
p = hf_hub_download(repo_id=repo, repo_type="dataset", filename=fname, token=token)
sys.stdout.write(p)
except Exception:
sys.exit(1)
PY
)" || RESTORE_PATH=""
if [ -n "$RESTORE_PATH" ] && [ -f "$RESTORE_PATH" ]; then
echo "Restore file found: $RESTORE_PATH"
tar -xzf "$RESTORE_PATH" -C "$STORAGE_DIR" || true
else
echo "No backup yet. (First run is normal.)"
fi
# 2) 后台:定时备份(只备份 users/bookSource/bookshelf)
backup_loop() {
while true; do
TS="$(date -u +%Y%m%d_%H%M%S)"
TMP_DIR="/tmp/reader_min_backup_$TS"
TMP_TGZ="/tmp/$BACKUP_FILENAME"
mkdir -p "$TMP_DIR"
# 生成最小文件清单
(
cd "$STORAGE_DIR" || exit 0
# 1) 用户文件
[ -f "data/users.json" ] && echo "data/users.json"
# 2) 每个用户的书源/书架
# 常见路径类似:data/<userid>/bookSource.json, data/<userid>/bookshelf.json
find data -maxdepth 2 -type f \( -name "bookSource.json" -o -name "bookshelf.json" \) 2>/dev/null || true
) > "$TMP_DIR/filelist.txt"
if [ -s "$TMP_DIR/filelist.txt" ]; then
(cd "$STORAGE_DIR" && tar -czf "$TMP_TGZ" -T "$TMP_DIR/filelist.txt") || true
if [ -f "$TMP_TGZ" ]; then
echo "[backup $TS] Uploading minimal backup..."
python3 - <<PY
import os
from huggingface_hub import HfApi
api = HfApi()
api.upload_file(
path_or_fileobj=os.environ["TMP_TGZ"],
path_in_repo=os.environ["BACKUP_FILENAME"],
repo_id=os.environ["BACKUP_REPO"],
repo_type="dataset",
token=os.environ.get("HF_TOKEN"),
commit_message=f"reader minimal backup {os.environ.get('TS')}",
)
print("upload ok")
PY
fi
else
echo "[backup $TS] Nothing to backup yet."
fi
rm -rf "$TMP_DIR" || true
sleep "$BACKUP_INTERVAL"
done
}
export TS TMP_TGZ
backup_loop &
# 3) 端口转发(HF 要 7860;Reader 跑 8080)
echo "[2/3] Start socat 7860->8080"
socat TCP-LISTEN:7860,fork TCP:127.0.0.1:8080 &
# 4) 启动 Reader,并明确 storage 路径
echo "[3/3] Start Reader..."
exec java -Dreader.app.storagePath=/storage -jar /app/bin/reader.jar --server.port=8080
SH
RUN chmod +x /app/run.sh
ENTRYPOINT ["/app/run.sh"] |