feat: 新增备份恢复与公网加固
- 新增备份管理页与 API:在线快照、自动周期备份、按份数清理、下载、一键恢复(恢复前自动兜底) - 新增 /profile/export,普通用户可导出本人全部数据(不含 Cookie 明文) - 修复 X-Forwarded-For 可伪造导致三道 IP 防线失效,统一走 client_ip() 取客户端地址 - 取消 admin123 硬编码默认口令,留空则生成随机初始口令并仅打印一次 - .dockerignore 排除 backups/ 并加构建期断言,防止密钥随镜像分发 - 新增会话版本号,改密/停用/删除及恢复备份后其他会话立即失效 - 新增容器资源上限、采集跨度硬顶 31 天、重操作最小间隔与并发 409 - 新增访问日志、HSTS 条件下发、口令黑名单、验证码抗模板匹配、instance.json 0600 - 版本号升至 1.4.0,同步更新 README、SECURITY、.env.example 与 compose 配置
这个提交包含在:
+15
-4
@@ -26,7 +26,7 @@ FROM python:3.13-slim AS runtime
|
||||
|
||||
LABEL org.opencontainers.image.title="WorkBuddy Portal" \
|
||||
org.opencontainers.image.description="WorkBuddy 积分用量采集 / 存储 / 呈现一体化门户" \
|
||||
org.opencontainers.image.version="1.3.0" \
|
||||
org.opencontainers.image.version="1.4.0" \
|
||||
org.opencontainers.image.source="https://git.iwali.top/wangchuanli/workbuddy-portal"
|
||||
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
@@ -36,6 +36,7 @@ ENV PYTHONUNBUFFERED=1 \
|
||||
PATH="/opt/venv/bin:$PATH" \
|
||||
WB_DATA_DIR=/app/data \
|
||||
WB_LOG_DIR=/app/logs \
|
||||
WB_BACKUP_DIR=/app/backups \
|
||||
WB_HOST=0.0.0.0 \
|
||||
WB_PORT=8848
|
||||
|
||||
@@ -55,16 +56,26 @@ WORKDIR /app
|
||||
# --chown 让非 root 用户能读写挂载卷之外的文件;.dockerignore 已挡掉数据与日志
|
||||
COPY --chown=app:app . .
|
||||
|
||||
# 构建期断言:万一 .dockerignore 漏掉 backups/,在这里直接失败。
|
||||
# 只靠「记得改 .dockerignore」不可靠 —— 备份归档里有 instance.json(含
|
||||
# SECRET_KEY 与 cookie_key),进了镜像层就是整库密钥随镜像分发,且**无法**
|
||||
# 用后续的 RUN rm 抹掉(只会多留一个含内容的只读层)。让构建自己拒绝。
|
||||
RUN set -eux; \
|
||||
if [ -n "$(ls -A /app/backups 2>/dev/null)" ]; then \
|
||||
echo "ERROR: /app/backups 里有内容被打进镜像层 —— .dockerignore 漏了 backups/" >&2; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
RUN set -eux; \
|
||||
chmod +x /app/docker/entrypoint.sh /app/docker/healthcheck.py; \
|
||||
mkdir -p /app/data /app/logs; \
|
||||
chown -R app:app /app/data /app/logs; \
|
||||
mkdir -p /app/data /app/logs /app/backups; \
|
||||
chown -R app:app /app/data /app/logs /app/backups; \
|
||||
python -c "import workbuddy_portal, flask, waitress; print('deps ok', flask.__version__)"
|
||||
|
||||
USER app
|
||||
|
||||
EXPOSE 8848
|
||||
VOLUME ["/app/data", "/app/logs"]
|
||||
VOLUME ["/app/data", "/app/logs", "/app/backups"]
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=6s --start-period=20s --retries=3 \
|
||||
CMD ["python", "/app/docker/healthcheck.py"]
|
||||
|
||||
在新工单中引用
屏蔽一个用户