Skip to content

Repository files navigation

无聊湾 · BoringBay

无聊人的中继站。发现独立博客,也让独立博客彼此发现。

线上站点 · 公开流量分析 · 加入无聊湾 · 排行榜

无聊湾是一个基于成员互链和匿名访问统计的独立博客联盟。它保留原有的成员列表、UV/RV、等级、排行榜、实时动态与 Badge,同时加入每日航线、公平随机探索、本地护照、漂流瓶文章和分享卡等轻量玩法。

V2 采用渐进增强:关闭功能开关时仍提供原有体验;开启后也不要求注册账号,成员已有的链接和 Badge 无需修改。

功能

原有能力继续兼容

  • 成员站点展示、UV(独立访客)、RV(链入访客)与等级
  • 经典总排行、加入流程和实时湾内动态
  • /api/badge/:domain、/api/icon/:domain、/api/favicon/:domain
  • /api/ws WebSocket 接口及现有成员数据、历史统计

V2 探索体验

  • 今日航线:每天稳定生成同一条五站路线,兼顾主题差异与曝光公平
  • 随便逛逛:优先探索尚未访问、近期曝光较少的站点
  • 无聊护照:访问、收藏、邮戳与成就保存在浏览器本地,无需登录
  • 最新漂流瓶:成员自愿提供 RSS/Atom,只展示标题、短摘要、时间和原文链接
  • 可分享路线:固定日期链接、Open Graph 信息和 SVG 分享卡
  • 三类榜单:30 天活跃榜、7 天上升榜、保留历史意义的经典总榜
  • 状态观察:按最后活动和连续健康检测分为活跃、安静、观察、可移除候选;永不自动删除成员
  • 公开流量分析:任何人可查看全站或单个成员的 UV、RV、导出点击、趋势、时段、国家与来源

公开流量分析

/analytics 提供全站总览,/analytics/:domain 提供公开成员页。数据只来自无聊湾现有可验证链路:

  • 成员页面加载 Badge 产生的去重 UV;
  • 访客从成员域名进入无聊湾产生的去重 RV;
  • 访客从首页、排行榜、路线、随机探索和漂流瓶跳向成员的导出点击。

这些数字不代表成员博客的全部访问量,也不要求成员安装新的统计脚本。UV/RV 保持原有四小时去重语义,导出点击不会影响排行榜。

最近 90 天保留小时级聚合,日级总量长期保留。国家、来源域名和内部入口的单项计数小于 3 时只显示在“其他”中;总 UV、RV 和导出点击仍精确展示。系统不保存原始访问事件或可回溯的访客轨迹。

技术栈

  • Rust 2021(工具链固定为 1.98.1)
  • Axum 0.8 + Askama 0.16
  • Diesel 2.3 + SQLite
  • 服务端渲染,少量原生 ES Modules
  • 加法数据库迁移;启动时自动执行待处理迁移

项目默认监听 0.0.0.0:3000。

本地运行

1. 准备环境

  • Rust stable(项目已使用 Rust 1.98.1 验证)
  • SQLite 由 libsqlite3-sys bundled feature 提供,无需单独安装开发库
  • Node.js 仅用于浏览器本地护照测试

2. 配置并启动

export SYSTEM_DOMAIN=localhost:3000
export DATABASE_URL=/tmp/boringbay.db
export TRUSTED_PROXY_MODE=disabled

cargo run --release

浏览器打开 http://localhost:3000。首次启动会创建数据库并自动执行全部迁移。

环境变量

变量 必填 默认值 说明
SYSTEM_DOMAIN 是 无 对外域名;本地可用 localhost:3000
DATABASE_URL 是 无 SQLite 文件路径
BORINGBAY_V2_ENABLED 否 true V2 默认开启;false/no/off/0 可临时回退到旧界面
TRUSTED_PROXY_MODE 否 正式域名为 boringbay.com 时是 cloudflare,其他域名为 disabled 可选 disabled 或 cloudflare

正式站为兼容原有 UV/RV 统计与实时访问事件,在没有显式配置时继续信任 Cloudflare 请求头。其他域名默认保持 disabled;只有服务确实位于 Cloudflare 后方时才应设置 TRUSTED_PROXY_MODE=cloudflare,直连部署必须显式保持 disabled,避免信任客户端伪造的请求头。

加入无聊湾

  1. Fork 本仓库。
  2. 在 resources/membership.json 中使用未占用的数字 ID 添加站点。
  3. 将经典 Badge 或 V2 Badge 放到你的网站。
  4. 提交 Pull Request。

成员示例:

{
  "123": {
    "domain": "example.com",
    "icon": "https://example.com/icon.png",
    "name": "示例博客",
    "description": "一句话介绍你的站点",
    "github_username": "owner/repository",
    "tags": ["技术", "生活"],
    "feed_url": "https://example.com/feed.xml"
  }
}
  • domain 不要包含协议或路径。
  • tags 与 feed_url 均为可选字段,不填写不会影响成员资格。
  • feed_url 只接受公开可访问的 HTTPS RSS/Atom 地址;正文不会被镜像,点击始终回到原博客。
  • 暂时隐藏站点可使用 "hidden": true。

Badge

经典 Badge(继续兼容):

<a title="无聊湾 🥱 The Boring Bay" href="https://boringbay.com">
  <img height="18" src="https://boringbay.com/api/badge/example.com" alt="无聊湾">
</a>

V2 Badge(可选):

<a title="无聊湾 🥱 The Boring Bay" href="https://boringbay.com">
  <img height="36" src="https://boringbay.com/api/badge-v2/example.com" alt="无聊湾 V2">
</a>

仅展示图标、不记录访问:

https://boringbay.com/api/icon/example.com
https://boringbay.com/api/favicon/example.com

排行与成员状态

  • 30 天活跃榜:默认榜,按近期 UV/RV 展示真实互动。
  • 7 天上升榜:比较最近 7 天与此前 7 天,让小站和新站也有曝光机会。
  • 经典总榜:保留现有历史累计数据。
  • 状态观察:最后活动同时考虑最后受访和最后链入;30 天安静、60 天且连续检测异常进入观察、90 天且持续异常才成为人工复核候选。

探索、护照、分享事件与正式 UV/RV 分开存储,不会因为完成航线或分享链接而刷榜。任何状态都不会触发自动删除。

Feed、安全与隐私

  • Feed 仅接受成员主动配置的 HTTPS 地址。
  • DNS 解析、目标 IP 与每次重定向都会重新校验,拒绝私网、回环、链路本地等地址。
  • 最多跟随 2 次重定向;单次响应上限 1 MiB;只接受 XML/RSS/Atom 类型。
  • 拒绝 DTD/外部实体,摘要转为纯文本并统一转义。
  • Feed、健康检查失败只降级对应模块,不影响首页、排行或 Badge。
  • 不记录或通过 WebSocket 广播完整 IP;访客去重使用进程内短期 HMAC 标识。
  • 实时动态由服务端先脱敏 IP:IPv4 仅保留首尾段,IPv6 仅保留前后各两段。脱敏值只进入当次 WebSocket 弹窗,不写数据库、日志或历史分析。
  • 公开分析只存小时/日聚合;国家、来源和入口小于 3 次时合并为“其他”。

测试

cargo fmt -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --locked --all-targets
node --test tests/*.test.mjs
node --check resources/static/app.js
node --check resources/static/discovery.js
node --check resources/static/passport.js
cargo build --release --locked

测试覆盖旧 API 兼容、数据库迁移、三类排行、30/60/90 天状态边界、确定性每日航线、公平随机、Feed 解析与安全清洗、V1/V2 页面、本地护照、脱敏 IP 与公开聚合分析。

部署与升级

生产升级建议:

  1. 备份 DATABASE_URL 指向的 SQLite 文件。
  2. 使用同一份 migrations/、resources/、templates/ 与新二进制启动。
  3. 不设置 BORINGBAY_V2_ENABLED,按默认开启的 V2 检查首页、三类排行、今日航线、Badge、Feed 和 WebSocket。
  4. 如果需要快速回退界面,可临时设置 BORINGBAY_V2_ENABLED=false;旧页面和原有 API 仍可继续使用。
  5. 保留上一版二进制与数据库备份,以便快速回滚。

SQLite 在建池前由单连接切换到 WAL;池连接启用外键和 5 秒 busy timeout,降低统计、Feed 与健康任务并发时的锁竞争。

Dockerfile 面向 CI 生成的 artifact/$TARGETPLATFORM/naive,并把 migrations/、resources/、templates/ 复制到 /webapp。运行容器时应持久化 /webapp/data,并设置上述环境变量。

自动构建与发布

  • Pull Request 会运行格式检查、严格 Clippy、Rust/Node 测试,分别构建 amd64 与 arm64 发布二进制,并实际组装多架构容器但不推送。
  • 合并到 main 后,同一工作流使用同一提交产生的两个二进制构建多架构镜像,不再从另一个工作流猜测或重新检出提交。
  • 镜像发布到 ghcr.io/cantoblanco/boringbay:latest,同时保留 sha-<完整提交 SHA> 标签便于追溯和回滚。
  • 第三方 Actions 均固定到完整提交 SHA;发布镜像包含 provenance 与 SBOM。

主要路由

路由 用途
/ 首页和成员列表
/rank 排行榜和成员状态
/analytics 全站公开流量分析
/analytics/:domain 单个成员公开流量分析
/route/:date 指定日期的五站航线
/join-us 加入说明与 Badge 示例
/api/discovery/today 今日航线 JSON
/api/share/route/:date.svg 航线 SVG 分享卡
/api/events 白名单匿名产品事件
/api/ws 实时湾内动态

项目结构

src/                  Rust 应用、排行、分析、探索、Feed、健康与分享逻辑
templates/            Askama 服务端模板
resources/static/     CSS 与原生 JavaScript
resources/membership.json
migrations/           Diesel SQLite 迁移
tests/                兼容、迁移、页面、Feed 与护照测试
docs/superpowers/     V2 设计、风险登记与实施计划

详细方案:

贡献者

naiba

Kris 王九弦SZ·Ninty 懋和道人 Frederick Chen JB20CM Mello MCTGyt WoLeo-Z 如形 Kokona_Shiki AdeleNaumann gitmba jipa233 mcenahle Kyomu ShSuperyun 熊宝 枫韵 圆周率3014 yunze taoziwei qiyao guangzhoueven 伍拾柒 Caesar Handsome Mauzhu Qindarkstone SEYYl SaboZhang The hanta Watermelonabc XCATX freedom2599 gogei2010 longchunxin lyle miniwater nieshilin sdfghjwmbkdouble sefvcf spiritlhl tech-fever 黑歌 lololololowe 澪度 lcrworld kufx it985 imshadow Kris gankudadiz dreamerhe114514 citihu LixdHappy 霄染 langpa 翔宇工作流 缘生 王兴家 MortalCat 星然♚ wumingblog KoBariDevฅ 辰渊尘 ChenDusk 小垃圾 夜白 yinzhuoqun Qiankun Xia xinye 嘿哟 xMoieo wzwzx Masone tianhukj Percival Zheng LBB Joker Jochen233 JianHao Yang Jackie Howie Xie HongShi211 Honesty HansJack Gil Schneider Echo846 Calyee Calvert Lee BlueLanM AndyJin Amitabha 9527DHX 2022471674/28.7 bbb-lsy07 awaae Zlemoni 𝖅𝖍𝖔𝖚𝖞𝖎 Zebin Yicheng Ding Veitzn UpXuu Txiao Meng Supermini233 Styunlen Senc-QWA SeerSu zheep Redcha Rabbit_xuan StarChen Peter267 OvO L

致谢

项目最初名为 NAiVe。无聊湾图标修改自熊大的 The Boring Studio。

About

🥱 无聊湾,欢迎加入

Resources

Stars

20 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages