真诚友善团结专业,共建你我引以为荣之社区。《常见问题解答》
❤️ 再忍不住,也不要做这种事啊 ❤️
24 / 24
3月 19 日

让我们感谢 @Cokertieba_024 大佬太强了 :tieba_087:
实现了 huggingface 的 webdav 同步,重启数据也不会丢失了

项目地址:

1. 创建 Dockerfile

FROM hectorqin/reader:latest RUN apk update && \ apk add --no-cache python3 python3-dev py3-pip curl libxml2-dev libxslt-dev gcc musl-dev && \ rm -rf /var/cache/apk/* RUN mkdir -p /logs /storage /file-uploads /data RUN chmod a+w /logs /storage /file-uploads /data ENV VIRTUAL_ENV=/opt/venv RUN python3 -m venv $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" RUN pip install --upgrade pip RUN pip install --no-cache-dir requests webdavclient3 COPY sync_data.sh /sync_data.sh RUN chmod +x /sync_data.sh CMD ["/bin/sh", "/sync_data.sh"]

README.md 末尾添加

app_port: 8080

2. 创建 sync_data.sh 文件

#!/bin/sh # 检查环境变量 if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then echo "Starting without backup functionality - missing WEBDAV_URL, WEBDAV_USERNAME, or WEBDAV_PASSWORD" exec java -jar /app/bin/reader.jar exit 0 fi # 设置备份路径 WEBDAV_BACKUP_PATH=${WEBDAV_BACKUP_PATH:-""} FULL_WEBDAV_URL="${WEBDAV_URL}" if [ -n "$WEBDAV_BACKUP_PATH" ]; then FULL_WEBDAV_URL="${WEBDAV_URL}/${WEBDAV_BACKUP_PATH}" fi # 下载最新备份并恢复 restore_backup() { python3 -c " import sys import os import tarfile import requests from webdav3.client import Client options = { 'webdav_hostname': '$FULL_WEBDAV_URL', 'webdav_login': '$WEBDAV_USERNAME', 'webdav_password': '$WEBDAV_PASSWORD' } client = Client(options) backups = [file for file in client.list() if file.endswith('.tar.gz') and file.startswith('reader_backup_')] if not backups: print('No backup files found') sys.exit() latest_backup = sorted(backups)[-1] with requests.get(f'$FULL_WEBDAV_URL/{latest_backup}', auth=('$WEBDAV_USERNAME', '$WEBDAV_PASSWORD'), stream=True) as r: if r.status_code == 200: with open(f'/tmp/{latest_backup}', 'wb') as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) if os.path.exists(f'/tmp/{latest_backup}'): with tarfile.open(f'/tmp/{latest_backup}', 'r:gz') as tar: tar.extractall('/storage') print(f'Successfully restored backup from {latest_backup}') else: print('Failed to download backup file') else: print(f'Failed to download backup: {r.status_code}') " } # 首次启动时下载最新备份 echo "Downloading latest backup from WebDAV..." restore_backup # 同步函数 sync_data() { while true; do echo "Starting sync process at $(date)" if [ -d /storage ]; then timestamp=$(date +%Y%m%d_%H%M%S) backup_file="reader_backup_${timestamp}.tar.gz" # 压缩数据目录 tar -czf "/tmp/${backup_file}" -C /storage . # 上传新备份到WebDAV curl -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "/tmp/${backup_file}" "$FULL_WEBDAV_URL/${backup_file}" if [ $? -eq 0 ]; then echo "Successfully uploaded ${backup_file} to WebDAV" else echo "Failed to upload ${backup_file} to WebDAV" fi # 清理旧备份文件 python3 -c " import sys from webdav3.client import Client options = { 'webdav_hostname': '$FULL_WEBDAV_URL', 'webdav_login': '$WEBDAV_USERNAME', 'webdav_password': '$WEBDAV_PASSWORD' } client = Client(options) backups = [file for file in client.list() if file.endswith('.tar.gz') and file.startswith('reader_backup_')] backups.sort() if len(backups) > 2: to_delete = len(backups) - 2 for file in backups[:to_delete]: client.clean(file) print(f'Successfully deleted {file}.') else: print('Only {} backups found, no need to clean.'.format(len(backups))) " 2>&1 rm -f "/tmp/${backup_file}" else echo "/storage directory does not exist, waiting for next sync..." fi SYNC_INTERVAL=${SYNC_INTERVAL:-600} sleep $SYNC_INTERVAL done } # 后台启动同步进程 sync_data & # 启动应用程序主进程 exec java -jar /app/bin/reader.jar

默认保留 2 个备份文件,600s 同步一次

3. 注册 webdav 并开启传输权限

4. 填入相关变量

WEBDAV_URL # https://jike.teracloud.jp/dav WEBDAV_BACKUP_PATH # 备份文件夹名(备份文件夹,需要自行在网盘中创建,如reader) WEBDAV_USERNAME # 用户名 WEBDAV_PASSWORD # 连接密码,第3步获取到的 SYNC_INTERVAL # 同步时间,默认600

项目变量推荐

SPRING_PROFILES_ACTIVE=prod READER_APP_USERLIMIT=50 #用户上限,默认50 READER_APP_USERBOOKLIMIT=200 #用户书籍上限,默认200 READER_APP_CACHECHAPTERCONTENT=true #开启缓存章节内容 V2.0 # 下面都是多用户模式配置 READER_APP_SECURE=true #开启登录鉴权,开启后将支持多用户模式 READER_APP_SECUREKEY=adminpwd #管理员密码 建议修改 READER_APP_INVITECODE=registercode #注册邀请码 建议修改,如不需要可注释或删除(建议添加,防止他人注册)

5. 在 cloudflare 进行反代 (非必须)

export default { async fetch(request, env) { const url = new URL(request.url); url.host = '你的地址'; return fetch(new Request(url, request)) } }

赞美 @Cokertieba_024 佬!

巨佬太强了 :tieba_087:

太强了 reno 佬 :tieba_087:

赞美巨佬们,太强了 :tieba_087:

上次访问

管理者账户是什么 reader 吗
我使用注册码注册账户登录了,后续使用管理密码进行管理.

支持佬,已经部署上了

此话题将在最后一个回复的1 个月后关闭。