Files
server-ops/daily_2026-06-15.md

21 KiB
Raw Blame History

2026-06-15 工作日志

Calibre-Web 电子书库部署

  • Docker 部署 linuxserver/calibre-web:latest,端口 8083
  • Caddy 反代 books.xybkwd.topHTTPS 自动证书)
  • nav 导航页新增"电子书库"卡片琥珀色书籍图标book SVG
  • 所有卡片状态统一为"运行中"
  • 要闻页面字体再次加大(移动端摘要 18px标题 19px

Gitea 仓库 ebook-library

  • 通过 Gitea API 创建 fxy/ebook-library 仓库fxy token: 513f4f51...
  • 服务器 ~/ebook-library/ 初始化目录结构scripts/、docs/、config/
  • README.md + .gitignore 已推送

TIMELINE.md 修复

  • TIMELINE.md 被 shell 转义弄乱,从 git 历史恢复原始内容后追加 Calibre-Web 条目

DNS 发现

  • books.xybkwd.top DNS 已解析到 43.163.225.30(可能是通配符或之前手动加的)
  • 腾讯云 DNS API 密钥未找到Lucky 配置加密、服务器/本地全面搜索无果)
  • 如需 API 密钥自动化 DNS需冯总提供腾讯云 SecretId/SecretKey

用户偏好确认

  • 冯总明确要淡化"beast"称呼,新仓库用 fxy 组织,不使用 beast 命名

安全排查与加固

  • 全面排查服务器安全状态SSH 配置、防火墙、端口暴露、服务认证
  • Lucky 已彻底删除(/opt/lucky/ + Docker 残留全部清除)
  • 发现 Caddy basicauth 全部缺失(之前设置后被取消)
  • 已恢复gitea / dashboard / memo / nav / books 全部加上 basicauthfxy / Qiyun2025!
  • 博客和 Vaultwarden 不加博客公开Vaultwarden 自身有登录)
  • 验证通过:无密码返回 401带密码返回 200
  • 🔴 安全铁律已固化:严禁取消 basicauth调试用 localhost 不改 Caddyfile
  • 发现 Shadowsocks 服务在端口 31567代理服务正常
  • ufw 残留端口 16601Lucky 残余待清理9001 待清理

DeepSeek 余额显示修复

  • 问题:两个 cron 脚本都在写 /var/www/nav/data/balance.json,每小时整点互相覆盖
    • inspiration-collector/tools/deepseek_balance.py — 扁平格式JS 可读
    • ai-chat/fetch_balance.py — API 原始格式(balance_infos 嵌套JS 解析失败
  • 修复:删除 ai-chat/fetch_balance.py 的 cron只保留格式正确的那个
  • 立即重跑脚本,余额恢复显示 ¥7.58

栖云个人服务部署方案 v2

  • 生成完整方案文档(栖云个人服务部署方案_v2.md),覆盖 8 个方向:
    1. 全文搜索Meilisearch
    2. 书影音管理Ryot + Calibre-Web
    3. n8n 自动化(资源较重,建议后置)
    4. RSS Hub + Miniflux
    5. 图床Lsky Pro
    6. 自动化抓取changedetection.io + Python 爬虫)
    7. 语音助手(极简 Web 方案)
    8. 微信读书同步weread-exporter
  • 资源预算:全部部署内存 +950MB磁盘 +1.35GB,当前可用 1.5G/45G可行但偏紧
  • 建议分三批推进P0 优先:微信读书同步 + 图床 + 全文搜索

Memos 同步修复

  • 问题:手机 App 同步不了,报"未能读取数据,格式不正确"
  • 原因Caddy basicauth 拦截了 Memos API 请求App 无法通过 basicauth 认证
  • 修复memo.xybkwd.top 去掉 basicauthMemos 自身有用户登录系统)
  • 更新安全铁律Memos 和 Vaultwarden 不加 basicauth自身有认证

Memos API 调用踩坑记录(重要经验,已固化到 MEMORY.md

  • 协议Memos 用 Connect RPCPOST + JSON不是 RESTful GET
  • 接口POST /memos.api.v1.MemoService/ListMemos
  • 字段名:时间字段是 createTime(不是 createdTime/created_at),内容字段是 content
  • 外网不可调Caddy 反代 memo.xybkwd.top 无法正常转发 RPC 请求,必须 SSH 到服务器走 localhost:5230
  • 认证Bearer token存在服务器 secrets/secrets.jsonmemos_token 字段
  • 本次踩坑:先用外网 REST 尝试404→ 再试 v1 路径404→ 最终通过 SSH localhost + Python requests 才成功提取数据

海康威视参观学习

  • 冯总作为"90后四级副职培训班"学员(单位组织,浙大培训)参观海康威视总部
  • 核心洞察海康真正厉害的不是图像技术而是3万SKU的生产排程和供应链管理能力
  • 生成经历v1凭对话记忆要点不全→ 用户要求查 Memos → v3基于真实 Memos2101字→ v4修正身份为培训班学员不限篇幅4260字
  • 教训:生成课程/参观总结前,必须先从 Memos 提取真实记录,不能仅凭对话上下文编造;必须确认用户身份
  • 已推送 Giteainspiration-collector/ai-insights/daily/2026-06-15/
  • 手动总结流程已固化到 MEMORY.mdMemos提取→本地生成→SCP上传→Git推送→附件发送

灵感收集器标签功能改造

  • 改造了 daily_digest.pymemos_client.py,让标签在 AI 分析中真正发挥作用
  • 改动内容
    1. AI 提示词新增标签说明段落(标签揭示场景、延续性、主题聚类)
    2. memo 按标签分组展示(同主题归在一起,方便 AI 融会贯通)
    3. frontmatter 自动记录当天出现的所有用户标签
    4. 跨日标签延续检测(如果今天和昨天共享某标签,提醒 AI 关注连续性)
    5. 新增 list_memos_by_tag() 方法(支持按标签跨日检索)
    6. 新增 aggregate_tags() + group_memos_by_tag() 工具方法
  • 篇幅规则更新:除"简要分析"限 2000 字外,其余不设上限
  • 测试通过8 条 memos标签 90后四级副职培训班/浙江 正确识别并传入 AI
  • 已推送 Giteacommit 75586f1

灵感收集器标准话术库

  • 盘点了灵感收集器全部功能10 大模块:标签、每日分析、课程总结、周报、待办、新闻、余额、文库、运维、组合指令)
  • 生成了标准话术库文档(灵感收集器标准话术库.md),每句话术对应一个已实现的功能
  • 覆盖 cron 自动运行和手动触发两种场景

自动任务文档

  • 生成 docs/自动任务一览.md,记录服务器全部 14 条 cron + 6 个 systemd/Docker 服务
  • 包含数据流向图,梳理各任务间的依赖关系
  • 已推送 Giteacommit 36a507e
  • 更新机制:每次 cron 变更必须同步更新该文件

每日要闻扩展栏目

  • 新增 4 个栏目政策速递、AI/量化前沿、市场行情、深度解读
  • 新增 6 个 Python 脚本
    • fetch_policy.py / summarize_policy.py — 政策 RSS + AI 摘要
    • fetch_research.py / summarize_research.py — ArXiv AI/量化博客 RSS + AI 分类摘要
    • fetch_market.py — A股指数东方财富 API+ 加密货币CoinGecko API
    • deep_dive.py — 从要闻 Top1 选取DeepSeek 生成 800-1200 字深度分析
  • 新增 6 条 cron:政策/研究每6h抓取+摘要市场每1h深度解读每天22:35
  • 改造 brief.html新增市场行情顶栏红涨绿跌、sidebar 合并所有栏目、深度解读卡片置顶、5 分钟自动刷新
  • 数据流6 个 RSS 源 → 原始 JSON → AI 摘要 JSON → brief.html 并行加载
  • 测试结果政策15条、研究37条3分类、市场8条、深度解读1条美伊停火分析
  • 自动任务文档更新至 v1.1
  • 已推送 Giteacommit f31c741 + 0da3fc7

每日要闻 UI 修复12:42~12:50

问题 1市场行情顶栏太丑

  • 原版单行水平滚动A股和加密货币混在一起排列混乱
  • 修复改为双行布局A股一行、加密一行每个指数/币种用 chip 卡片样式(带边框、圆角、背景),方向符号 ▲▼ 配色区分(红涨绿跌)

问题 2所有分类栏目显示的都是深度解读

  • 原因:深度解读卡片是独立的 deepDiveContainer,放在所有 cat-section 之外,但 sidebar 没有深度解读的独立 tab只有第一个新闻分类 tab 是 active 的
  • 修复:深度解读作为独立的 sidebar tab排在第一位点击只展示深度解读内容其余 tab 各自对应自己的新闻分类。switchTab 改用 data-tab 属性匹配

问题 3ETH 行情"不见"(实际是 change_pct 显示重复)

  • 根因:fetch_market.py 输出 change_pct: "▲ 2.26%"(含方向符号),前端 renderMarket 又自行追加了一个 chg-icon ▲,导致显示为 ▲ ▲ 2.26%,视觉上很乱
  • 修复:后端 change_pct 改为纯数值 "2.26%",方向由 is_up 布尔值控制,前端统一渲染方向符号
  • 附加A股东方财富 API timeout 从 10s 提高到 15s减少超时失败东京服务器到国内 API 延迟不稳定)
  • 已推送 Giteacommit e3a18a2 + d86bede

经验固化:前后端数据契约

  • 铁律JSON 数据输出纯数值/布尔值,不包含渲染相关的装饰符号(▲▼ 箭头、$ 货币符号等尽量少)
  • 方向/颜色/图标等展示逻辑统一由前端处理,避免前后端重复导致显示混乱
  • A 股行情接口 timeout 需 ≥15s东京→国内 API 链路不稳定)

新闻发布时间 pub_time 功能14:30~14:50

需求

  • 冯总要求新闻卡片显示发布时间,判断新闻即时性

实现方案:后端回填 + 前端展示

  • 后端RSS 原始数据已有 published 字段,但 AI 摘要脚本输出 JSON 时未保留
  • 方案AI 摘要输出后,用原始 RSS 的 published标题精确匹配 + 前20字符模糊匹配回填 pub_time
  • 时间格式:当天显示 HH:MM,非当天显示 MM-DD HH:MM
  • 匹配率news 96/102 (94%)、policy 8/15 (53%)、research 33/37 (89%)
  • 依赖python3-dateutildateutil.parser.parse() 解析各种 RSS 时间格式

修改文件

  • summarize_news.py v2新增 build_time_lookup() + match_pub_time()AI 提示要求保留原标题(匹配关键)
  • summarize_policy.py v2同上
  • summarize_research.py v2同上
  • brief.html:新闻卡片 badge 行(.badge)改为 flex 布局,右侧显示 .pub-time
  • backfill_pubtime.py:一次性脚本,给已有数据补填 pub_time
  • 已推送 Giteacommit eda0534

诸暨枫桥经验学习考察总结15:34

  • 从 Memos 提取原始记录1条 memo用 DeepSeek API 生成课程分析2148字/7分钟阅读
  • 内容:枫桥经验陈列馆参观 + 枫源村老书记骆根土座谈
  • 关键概念已补充背景:枫桥经验历史、千万工程、四前工作法、四先四早、枫桥三贤等
  • 已推送 Giteacommit 8ab1b3c

🔴 模型选择铁律14:47 冯总严令18:48 补充界限)

  • 智能体使用冯总积分时只准用 DeepSeek v4任何步骤不得切换到其他模型
  • 禁止智能体调用 GLM 模型(任何 GLM 系列均禁用)
  • 补充:冯总自行购买的 API Key 由冯总自由切换,不在本禁止之列

手动日报触发 & 对比验证16:01

  • 手动触发 daily_digest.py生成今日日报2916字/4条灵感含海康+枫桥+数字基建
  • 与课程总结诸暨枫桥2148字对比日报=思考输出(融会贯通),课程总结=知识存档(结构化笔记),互补关系
  • 冯总满意两份文档,确认保留

冯总对写作体系的规划16:07 确认)

  • 日报:保持每天 22:30 cron 自动执行(当前培训期主要分析学习内容,后续加入工作事务)
  • 课程总结/参观总结:手动触发,不设 cron冯总自己决定什么时候生成
  • 写作体系方向:后续会开发多种写作模板,对文库、灵感库进行更多维度的发掘、梳理、分析和写作
  • 本质上冯总在构建一个"个人知识管理 + 多维度写作输出"体系,灵感收集器是其中的核心引擎

待办推送修复16:21

  • 问题:extract_todos.py 的 cron 每 30 分钟跑一次,但今天日报的待办没有推送到待办系统
  • 根因(双重):
    1. AI 输出格式变了:从 [ ] checkbox 变成 1. **粗体**:描述,正则不匹配
    2. digest 文件路径变了:从 daily/YYYY-MM-DD_digest.md 变成 daily/YYYY-MM-DD/YYYY-MM-DD_digest_HHMMSS.md,脚本没递归子目录
  • 修复:extract_todos.py 升级为递归搜索 + 多格式匹配 + 模板标题过滤
  • 已手动清理 4 条误推的模板标题(【今日输入】等)
  • 测试结果8 条待办提取成功4 条有效待办推送到 API
  • 已推送 Giteacommit 1a3a211

第四小组政绩观学习研讨报告17:00

  • 冯总要求以第四小组名义撰写《关于习近平总书记地方工作期间坚持正确政绩观生动实践》学习研讨报告
  • 素材来源Memos 全部培训记录浙大3天课程+ 诸暨枫桥经验学习总结 + 海康威视参观总结 + 权威资料(求是网、央广网、中工网等)
  • 报告约4200字四个部分①政绩观核心要义 ②五个维度分析(战略定力/改革创新/为民情怀/担当作为/全面发展) ③第四小组学习收获 ④结语
  • 贴合课程实际枫桥经验、千万工程、八八战略、海康威视参观、科大讯飞参观、宇树科技讲座、数字浙江课程、章丰AI课程均有引用
  • 已推送 Giteacommit 79f166b
  • Word+PDF生成python-docx + Word COM接口符合公文格式GB/T 9704-2012标题和第四小组居中

Auto 模式 token 消耗排查18:36~18:45

  • 冯总报告过去2小时 token 消耗巨大,要求排查
  • 排查路径DB 逐表查询 → trace 文件分析 → 会话消耗对比
  • 我的错误:仅凭 sessions 表的 model 字段就下结论说"auto 选了大模型",没有核实实际调用的模型
  • 事实冯总去网页端对账后确认1600+ 积分全烧在 GLM 5.0 Turbo 上,该模型当天 14:47 已被冯总明令禁止使用
  • DB 里 session 标记为 deepseek-v4-flash,实际走的却是 GLM → sessions.model 字段不可信
  • 教训已写入跨项目用户级 MEMORY.md只信平台账单/API 日志,不信 DB 字段
  • 冯总明确了模型使用界限:自己的 API Key 自由切换,我使用积分时只能用 DeepSeek
  • 问题Caddy basicauth 导致浏览器每 ~1 小时要求重新输入密码,尤其是移动端。用户每天登无数遍,痛点明显
  • 根因HTTP Basic Auth 依赖浏览器缓存凭据,移动浏览器缓存策略不稳定,且跨子域不共享凭据
  • 方案:用 Python auth_proxyport 9002替换 Caddy basicauth改用 Session Cookie7 天过期HttpOnly, SameSite=Lax
  • 架构
    • Caddy → auth_proxy:9002 → 验证 session cookie → 代理到实际后端或提供静态文件
    • 无 cookie → 302 重定向到 auth.xybkwd.top/login?redirect=...
    • 登录后 Set-Cookie7 天有效,跨子域共享
  • 部署内容
    • /home/ubuntu/auth_proxy.py — Python HTTPServerbcrypt 验证密码HMAC-SHA256 签名 token
    • /etc/systemd/system/auth_proxy.service — systemd 服务,开机自启
    • /etc/caddy/Caddyfile — 去掉所有 basicauth改用 reverse_proxy localhost:9002
    • 新增 auth.xybkwd.top → 代理到 auth_proxy登录页面无额外认证
  • 测试结果
    • auth.xybkwd.top/login → 200登录页面正常渲染
    • nav.xybkwd.top无 cookie→ 302 跳转到 auth.xybkwd.top/login?redirect=...
    • POST 登录(正确密码)→ 302 + Set-Cookie7天
    • 带 cookie 访问 nav → 20035KB index.html 正常加载
    • 带 cookie 访问 dashboard → 20048KB 仪表盘正常
    • 带 cookie 访问 gitea → 20013KB gitea 正常
  • 安全性不降低bcrypt 密码验证不变cookie HttpOnly 防 XSSHMAC-SHA256 签名防篡改
  • 服务恢复正常blog/vaultwarden/memo 不受影响(没有经过 auth_proxy
  • 现象:用户报告"登录以后直接不跳转了"——带 cookie 访问各子域仍被 302 回登录页
  • 根因1Cookie 跨子域失效)Set-Cookie 没有 Domain=.xybkwd.top,浏览器只为 auth.xybkwd.top 存 cookie访问 nav.xybkwd.top 时不带 cookie
    • 修复:cookie_valDomain=.xybkwd.top;
  • 根因2语法错误导致服务崩溃:用 SSH heredoc 直接 patch Python 代码,导致 unterminated string literalauth_proxy 反复 crash/重启
    • 修复:本地 py_compile 验证语法 → SCP 上传,不再用 heredoc 写 Python
  • 根因3Set-Cookie 值带多余引号)format() 里用了中文引号 "",导致 sess="token..." 而不是 sess=token...,浏览器拒绝该 cookie
    • 修复:sed -i 去掉多余引号,验证 Set-Cookie: sess=eyJ...(无引号)
  • 根因4多轮 hotfix 弄坏代码):多次 heredoc patch 叠加,最终 verify_tokenSECRET_KEY 引用错乱
    • 修复:本地重写完整 auth_proxy_v2.py,语法验证通过,一次性 SCP 覆盖
  • 最终验证curl 完整链路):
    1. POST /login → 302 + Set-Cookie: sess=...; Domain=.xybkwd.top; Max-Age=604800
    2. 带 cookie 访问 / → 200返回 35KB index.html
    3. 带 cookie 访问 /api/todos → 200返回 JSON
  • 经验
    • 🔴 禁止用 heredoc 写 Python 到服务器SSH 转义规则复杂,极易引入不可见错误。正确流程:本地写 → py_compile 验证 → SCP 上传 → 重启
    • Cookie 跨子域必须显式设 Domain=.example.com,否则浏览器按当前域名限制
    • Set-Cookie 的 token 值不要加引号RFC 6265 不允许
    • 调试代理服务:用 curl -D /tmp/hdr.txt -H "Cookie: sess=..." http://localhost:9002/... 逐层验证
  • 已推送 Giteacommit pending

auth_proxy 事故 — Caddy 回滚19:34~19:57

事故经过

  • 19:34 冯总报告brief/dashboard/gitea 三服务同时"坏了"
  • 根本原因auth_proxy 替换了 Caddy 的反向代理层,但 auth_proxy 代理能力不完整
    • Gitea Web/API 请求被 auth_proxy 拦截后无法正常工作
    • dashboard /api/market-structure 等路径返回 404
    • brief 的静态文件被 auth_proxy 的 serve_static 错误处理

回滚操作

  1. 恢复 Caddyfile所有服务直接 reverse_proxy 到各自后端端口
  2. 保留 auth.xybkwd.top → localhost:9002auth_proxy 仅作登录门户)
  3. 当前状态:所有服务 200 正常

basicauth 恢复失败

  • 尝试恢复 basicauth 但 Caddy v2.11 的 hash 格式不兼容
  • Caddy v2.11 basic_auth bcrypt 要求的 hash 格式与 caddy hash-password 输出不一致
  • $$ 符号在 Caddyfile 中可能被解释为环境变量
  • 临时方案:无 auth 开放访问(安全缺口待修复)

🔴 铁律Git-First 部署原则冯总19:57确认

  • 所有配置变更必须先 commit 到 git 仓库,再部署到生产环境
  • 事故中幸亏能从 git 历史commit 6c35f31找回正确的 Caddyfile 版本,否则回滚将极为困难
  • 本次教训auth_proxy 调试过程中直接修改了 /etc/caddy/Caddyfile 和 /home/ubuntu/auth_proxy.py未及时 git commit这是一种危险的运维习惯
  • 行动计划:未来任何生产环境变更,必须:
    1. 先在 git 仓库修改并 commit
    2. 再从 git 部署到生产
    3. 回滚时直接从 git checkout
  • 更严格的版本:可以建立 /etc/caddy/ 的 git 仓库,与 Gitea 同步

已推送 Gitea

  • fxy/nav-page commit 41f8ded — rollback Caddyfile 到直接代理
  • beast/server-ops commit 438245a — CHANGELOG v1.2.0 + 铁律记录

双认证方案上线20:00~20:08

  • 架构Caddy @authed cookie 匹配 + basic_auth bcrypt 兜底
    • sess cookie → 直接放行7天免登录
    • 无 cookie → basicauth 要求用户名密码
    • auth.xybkwd.top/login → auth_proxy 签发 cookieDomain=.xybkwd.top
  • 测试全部 7/7 通过
  • 已推送 Giteafxy/nav-page commit a86991a

🏆 里程碑 V1 达成20:33

  • 冯总确认:所有服务正常,认证架构按预期运行
  • 认证架构定型Cookie 免登录7天+ 统一登录门户 auth.xybkwd.top
  • 完整快照已固化到 MEMORY.md 第 9 章「里程碑 V1」
  • 核心文件均已 git commit可秒级回滚
  • Gitea 仓库最新 commit
    • fxy/nav-page 1a80249 — CaddyfileCookie 路由 + 反代)
    • beast/server-ops a6e85c6 — auth_proxy + milestone_v1.md

Calibre-Web 配置踩坑20:35~21:30

问题1上传后卡死、加载慢

  • 根因:用宿主机 calibre 7.6calibredb 创建 metadata.db版本与 Calibre-Web 容器内库不兼容
  • 修复:清空书库,让 Calibre-Web 自己创建数据库

问题2路径无效"DB Location is not Valid"

  • 根因check_valid_db() 函数要求 metadata.db 必须存在且有 library_id
  • 修复:手动用 sqlite3 创建包含 library_id 的空数据库

问题3上传报错 "no such column: publishers.sort"

  • 根因:手动创建的 metadata.db 表结构不完整,缺少 publishers.sort 等列
  • 修复:用 calibredb add 创建完整规范的 metadata.db397KB vs 手动82KB

问题4配置保存后仍 redirect 到 dbconfig

  • 根因settings 表中 config_calibre_uuid 与 metadata.db 的 library_id.uuid 不匹配
  • 修复:更新 settings.config_calibre_uuid 匹配 metadata.db.library_id.uuid

最终状态

  • 中文界面 | 上传功能开启 | 站点标题"栖云书库"
  • 书库已有《道德经》1本上传功能正常
  • 数据库用 calibredb 创建schema 完整,后续不再报错
  • 关键经验Calibre-Web 的 metadata.db 必须用 calibredb 或 Calibre-Web 自身创建,不能手动 sqlite3