From b9d82e54c73f85dacbb0a2774591f5d6bd7a9ba9 Mon Sep 17 00:00:00 2001 From: kaireewu Date: Sun, 1 Nov 2026 00:51:57 +0800 Subject: [PATCH] feat(deploy): add Dockerfile and compose for server sync --- .dockerignore | 20 +++++++++ Dockerfile | 32 +++++++++++++ config.docker.example.json | 92 ++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 15 +++++++ 4 files changed, 159 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 config.docker.example.json create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a7daba6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +# 本地凭据与运行期数据 +config.json +config.json.bak +config.json.tmp +data/ + +# 开发与测试 +.venv/ +.uv/ +.pytest_cache/ +__pycache__/ +*.pyc +tests/ +tools/ + +# Git 与编辑器 +.git/ +.gitignore +.idea/ +.vscode/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..63ec349 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +# 咻咻满 Reaction 看板 —— 单体服务镜像 +# +# 运行:只读 Web + 调度 + Telegram(与 `python app.py` 等价)。 +# 配置挂载到 /config,数据挂载到 /data。 + +FROM python:3.14-slim + +ENV TZ=Asia/Shanghai \ + PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + PIP_NO_CACHE_DIR=1 + +WORKDIR /app + +RUN apt-get update \ + && apt-get install -y --no-install-recommends tzdata ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# 依赖锁定在 uv.lock 的 httpx 0.28.1;如需新增依赖请同步 pyproject.toml / uv.lock。 +RUN pip install --no-cache-dir "httpx==0.28.1" + +COPY app.py favsort.py ./ +COPY reaction_board ./reaction_board +COPY vendor ./vendor + +VOLUME ["/config", "/data"] +EXPOSE 8080 + +HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ + CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/api/health', timeout=3)" + +CMD ["python", "app.py", "--config", "/config/config.json"] \ No newline at end of file diff --git a/config.docker.example.json b/config.docker.example.json new file mode 100644 index 0000000..ca7d11f --- /dev/null +++ b/config.docker.example.json @@ -0,0 +1,92 @@ +{ + "bilibili": { + "read": { + "mid": 0, + "csrf": "从 read 账号 cookie 中的 bili_jct 取值", + "cookie": "只读账号的完整 Cookie(需含 SESSDATA、bili_jct、DedeUserID 等)" + }, + "write": { + "mid": 0, + "csrf": "从 write 账号 cookie 中的 bili_jct 取值", + "cookie": "写入账号的完整 Cookie(用于加入收藏夹和排序)" + } + }, + "telegram": { + "enabled": false, + "bot_token": "replace-with-telegram-bot-token", + "chat_id": 0 + }, + "web": { + "host": "0.0.0.0", + "port": 8080, + "auth_token": "replace-with-a-long-random-token", + "public_base_url": "" + }, + "storage": { + "database_path": "/data/app.db", + "backup_dir": "/data/backup", + "backup_keep_days": 14 + }, + "folders": [ + { "year": 2025, "media_id": 4451053851, "title": "咻咻满-reaction-2025" }, + { "year": 2026, "media_id": 3700023351, "title": "咻咻满 reaction 合集" } + ], + "track_fans": [37754047], + "up_blacklist_seed": [ + 261052419, + 1908537643, + 1701121088, + 542262, + 376316958, + 145178393, + 66389997, + 293976264, + 3026109 + ], + "schedule": { + "discover_minutes": 60, + "folder_sync_minutes": 60, + "full_folder_refresh_hours": 6, + "snapshot_at": "00:01", + "candidate_ttl_days": 7 + }, + "discover": { + "keywords": ["咻咻满 reaction", "咻咻满 充电"], + "pages": 2, + "window_days": 14 + }, + "notify": { + "min_score": 2, + "max_items_per_message": 10 + }, + "classify": { + "require_title": "咻咻满", + "self_mid": 37754047, + "positive": [ + "reaction", + "re", + "反应", + "看", + "听", + "初听", + "首次", + "点评", + "锐评", + "路人", + "震惊", + "双人" + ], + "charge": ["充电", "加急", "专场"], + "negative": ["歌切", "切片", "纯享", "搬运", "完整版"], + "duration_boost": { "gt_30min": 1, "gt_60min": 2 } + }, + "heat_weights": { + "view": 0.3, + "like": 0.2, + "coin": 0.2, + "favorite": 0.15, + "share": 0.1, + "reply": 0.03, + "danmaku": 0.02 + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c726672 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + board: + build: . + image: reaction-board:latest + container_name: reaction-board + restart: unless-stopped + init: true + environment: + TZ: Asia/Shanghai + ports: + - "8080:8080" + volumes: + - ./config.json:/config/config.json + - ./data:/data + command: ["python", "app.py", "--config", "/config/config.json"] \ No newline at end of file