Our Shopping List 5.0.0 介绍与选型指南
Our Shopping List 5.0.0 自托管多人实时协同购物清单的定位、架构、功能与量化选型结论:极轻量(三服务合计约 100 MiB 内存)但无内置认证,适合家庭/小团队内网部署。
Our Shopping List 5.0.0 介绍与选型指南
目标:面向准备自托管一套家庭/小团队购物清单服务的运维人员,给出 Our Shopping List(下文简称 OSL)的定位、架构、功能清单与量化选型结论。本文全部事实性数据(版本、星数、发布节奏、镜像体积、内存占用、竞品版本)已在 Linux 服务器实测/实查核对,查询与实测日期为 2026-10-24。
一、环境信息
本文数据采集与快速验证所依据的环境:
- 操作系统:Linux x86_64(内核 6.8,Docker 28.3.3)
- OSL 版本:5.0.0(官方发布镜像
ourshoppinglist/our-shopping-list:5.0.0) - 数据库栈:FerretDB 2.7.0 + PostgreSQL 17(documentdb 扩展,官方配套镜像)
- 服务端口:OSL 服务端监听 8080,实验中映射为宿主机 8132
- 部署形态:官方 compose 编排(app + ferretdb + postgres 三服务)
- 事实核查来源与日期:Codeberg 仓库/Releases(2026-10-24)、shields.io 星数徽章(2026-10-24)、Docker Hub 镜像 tag 列表(2026-10-24)、Grocy/KitchenOwl/Mealie 官方发布页(2026-10-24)
二、软件概述
2.1 一句话定位
OSL 是一个自托管的多人实时协同购物清单 Web 应用:把清单按「面板(Board)→ 清单(List)→ 条目(Item)」三层组织,家庭成员各自打开手机或电脑上的同一页面,任何人增删勾选条目,其他人秒级实时同步看到变化。它刻意做得极小——没有库存、没有食谱、没有账本,就是一张大家共享的购物清单。
2.2 项目身份与现状(实查 2026-10-24)
| 项目 | 事实 | 来源 |
|---|---|---|
| 作者 | nanawel(David Ladigs) | Codeberg 仓库页 |
| 许可证 | AGPL-3.0 | 仓库 LICENSE |
| 当前版本 | 5.0.0(2026-10-19 发布) | Codeberg Releases |
| 主仓库 | codeberg.org/nanawel/our-shopping-list | README |
| GitHub 旧仓库 | 2026-08-03 起归档为只读,README 指向 Codeberg | GitHub 仓库页 |
| 迁移原因 | 数据安全顾虑、GitHub 归属变更、平台功能变化;Codeberg 为欧盟非营利托管 | README「Migration to Codeberg」 |
| 星数 | 197(GitHub 归档后冻结,经 shields.io 徽章读取) | shields.io,2026-10-24 |
| 官方镜像 | ourshoppinglist/our-shopping-list(Docker Hub Sponsored OSS,自 v3.0.0 起) | Docker Hub / 5.0.0 Release 说明 |
⚠️ 注意:检索本组件时网上仍大量残留
github.com/nanawel/our-shopping-list链接,该仓库已只读归档,新版本(含 5.0.0)只在 Codeberg 发布。做版本核查时应以 Codeberg Releases 为准,GitHub 上能看到的最高 tag 只到 4.2.0(2026-03-03)。
2.3 版本节奏(实测 Codeberg tags feed)
从 tags 流水实查(2026-10-24),近 15 个月共 11 个版本 tag:
| 版本 | 发布日期 | 要点(Release 说明) |
|---|---|---|
| 4.0.0 | 2025-07-06 | PWA 支持迁移到 vite-plugin-pwa |
| 4.0.1 | 2025-08-13 | 临时标题修复 |
| 4.0.2 | 2025-09-14 | 修复 yargs 升级后 cli.js 回归 |
| 4.0.3 / 4.0.4 | 2025-10-11 / 10-17 | 依赖升级;axios 安全版本修正 |
| 4.0.5 | 2025-11-15 | 编辑对话框支持回车关闭 |
| 4.1.0 | 2026-02-04 | 依赖升级 |
| 4.1.1 / 4.1.2 | 2026-02-05 / 02-14 | 暗色模式配色修复;新增 VITE_APP_HIDE_FORCE_REFRESH_HINT |
| 4.2.0 | 2026-03-03 | CSV 粘贴批量建条目(#51) |
| 5.0.0 | 2026-10-19 | FerretDB 正式支持;修复列表名 XSS 漏洞;引入测试套件;依赖升级 |
关键解读:节奏约每 1~2 个月一个小版本,5.0.0 是一个带安全修复(XSS)+ 数据库栈转向(FerretDB 正式化)的大版本,新部署应直接从 5.0.0 起。5.0.0 的 XSS 修复也说明项目对安全问题仍有响应(详情见下文「限制」节——它没有认证,安全面主要靠网络位置)。
2.4 技术栈与架构
实测官方镜像与源码(server/package.json、client/package.json,2026-10-24 拉取)归纳的分层:
浏览器 / 手机 PWA(Vue 3.5 + Vite 构建的单页应用,vite-plugin-pwa)
│ HTTP + WebSocket(Socket.IO,路径 /socket.io/)
▼
OSL 服务端(Node.js 22 运行,Express 5.1 路由 + Mongoose 8.16 模型)
│ MongoDB 协议(mongoose 直连,端口 27017)
▼
数据库兼容层(二选一,官方均提供 compose 文件)
├─ FerretDB 2.7 + PostgreSQL 17(现役推荐,5.0.0 起正式支持)
└─ MongoDB 4.x~7.x(遗留方案,提供迁移脚本)
要点:
- 实时同步由 Socket.IO 承担:服务端启动日志实测
Serving socket-io on /socket.io/,心跳参数 pingInterval 25s / pingTimeout 20s,断线恢复窗口 30 分钟(对应VITE_APP_SOCKETIO_CSR_MAXDISCONNECTIONDURATION=1800000)。 - MongoDB 协议兼容层:服务端用 mongoose 直连 MongoDB 协议;5.0.0 起官方把 FerretDB + PostgreSQL 提为一等公民,新部署不必再引入 MongoDB 许可(SSPL)负担。
- 前端配置运行时注入:
VITE_APP_*系列变量不是构建期烧死,而是服务端启动时读取、经/config.js动态端点下发给前端(实测:修改VITE_APP_TITLE等变量重启后,curl /config.js立即反映新值)。这意味着改配置不需要重新构建,只需改环境变量重启。
💡 技术拓展:「MongoDB 兼容层」不止 FerretDB 一种。常见选项对比——
方案 原理 适用场景 MongoDB 原生 官方服务端直连 已有 MongoDB 运维体系;注意 SSPL 许可 FerretDB + PostgreSQL FerretDB 把 MongoDB 协议翻译成 PostgreSQL 存储 想留在 PostgreSQL 生态、规避 SSPL;OSL 5.0.0 起官方推荐 AWS DocumentDB / Azure Cosmos DB 云厂商托管兼容层 云上托管场景,自托管一般用不到 本文实测采用官方现役推荐「FerretDB 2.7 + PostgreSQL 17」,理由是免许可顾虑且部署、备份都回到 PostgreSQL 生态。
2.5 资源占用(实测)
三服务 compose 栈空载状态(docker stats --no-stream,2026-10-24 实测):
| 服务 | 内存占用 | CPU |
|---|---|---|
| OSL 主程序(Node.js 22) | 39.25 MiB | 0.07% |
| FerretDB 2.7 | 11.13 MiB | 0.00% |
| PostgreSQL 17(documentdb) | 49.30 MiB | 1.29% |
三服务合计约 100 MiB 常驻内存,镜像压缩体积 79 MB(Docker Hub 实查)。这是本文对比对象里最轻的一档——在 1 GB 内存的小主机/NAS 上与其他自托管服务共存没有压力。
三、核心架构
3.1 数据模型
三层结构,均以 UUID 为主键(实测 API 返回):
- Board(面板):顶层分组,有
name与唯一slug(URL 直接以 slug 访问,如/family)。 - List(清单):隶属某 Board,字段
name、boardId;删除时级联删除其下全部条目(实测)。 - Item(条目):隶属某 List,字段
name、qty(数值)、details、checked、checkedAt、createdById等。
另有两类特殊机制:单面板模式(VITE_APP_SINGLEBOARD_MODE=1 时全实例共享一块特殊面板,等价 v1 行为)与全局孤儿条目空间(不属于任何 List 的条目,可后续归位)。
3.2 接口面
同一进程内暴露三类接口(均实测):
- REST JSON API:
/boards、/lists、/items、/healthcheck等,无版本前缀、无认证;前端与外部脚本共用。 - Socket.IO WebSocket:
/socket.io/,条目级实时推送。 - CLI 工具:随镜像内置
cli.js(yargs 实现),提供board:create、board:find、list:find、list:move-to-board、item:find、config:show等子命令,主要用于建面板与 v1→v2 数据迁移。
💡 技术拓展:Web 应用的「API 无认证」常见做法对比——
做法 原理 适用场景 完全开放(OSL 现状) 任何能访问端口的人可读写 纯内网/VPN,信任所有可达者 反向代理加认证 Nginx/Apache 层挂 Basic Auth/OAuth2-Proxy 半公开暴露时的标准补救 应用内置账户体系 应用自己做登录 多租户/公网 SaaS OSL 走的是第一种,官方 README 不再提供内置登录。选型时必须接受「安全边界=网络位置」这一前提,否则应在上游加反代认证(部署层的做法见《Our Shopping List Docker Compose 部署指南》)。
四、功能特性
以下特性逐项在 5.0.0 实例上核对过(UI/API 实测 + README 2026-10-24 源):
- 多面板 + 多清单:面板按 slug 独立 URL 分享;可用
VITE_APP_SINGLEBOARD_MODE压回单一面板。 - 实时协同:Socket.IO 推送,实测条目增删改后其他连接秒级可见;断线后 30 分钟内可恢复会话。
- 条目字段:名称、数量(
qty数值)、备注(details)、勾选状态;勾选后按勾选时间排序(可配VITE_APP_CHECKED_ITEMS_HISTORY_SORT_FIELD/ORDER)。 - 两种显示模式:只看未勾选 / 只看已勾选历史。
- 搜索:清单内关键字过滤。
- 移动优先 + 手势:条目可滑动操作;PWA(可添加到主屏幕,5.0.0 起 vite-plugin-pwa;离线模式在路线图上,README 明示当前为 basic support)。
- CSV 粘贴批量建条目(4.2.0 引入,可配分隔符
VITE_APP_PASTE_CSV_SEPARATOR)。 - 国际化:12 种语言,含简体中文(
client/src/locales实查 12 个语言文件,中文zh在列),可强制/回退配置。 - 主题:
system / light / dark三档(VITE_APP_THEME)。 - robots.txt 可挂载替换:默认全站
Disallow: /,实测挂载自定义文件立即生效。
明确没有的功能(避免误选):用户账户与权限、库存/保质期管理、食谱、价格与记账、导出为移动原生应用、HTTPS 直连(TLS 由反代卸载)。
五、快速开始(最小可用示例)
前提:已按《Our Shopping List Docker Compose 部署指南》完成三服务部署(下文假设服务地址为 http://127.0.0.1:8132/,面板 slug 为 family)。部署完成后按下面三步即可用起来。
1)健康检查确认服务就绪:
curl http://127.0.0.1:8132/healthcheck
实测回显:
{"success":true}
2)浏览器打开面板 URL 即用:访问 http://<服务器IP>:8132/,从首页进入面板(或直接访问 http://<服务器IP>:8132/<面板slug>)。面板首次被访问时会自动创建(实测:对不存在的 slug 执行查询会直接建出该面板并返回 201),所以无需预先建面板,家人各自打开链接就能开始加清单、加条目。手机上用浏览器「添加到主屏幕」后获得类 App 图标(PWA)。
3)用 API 打通自动化(可选):以「向清单添加条目」为例(boardId/listId 先经查询接口获取,详见《Our Shopping List 5.0.0 API 使用详解》):
curl -s http://127.0.0.1:8132/lists/4ff671d0-9517-45a1-bd7a-c3c8cdf9d18b/items \
-X POST -H 'Content-Type: application/json' \
-d '{"name":"牛奶","qty":2}'
实测回显(输出节选):
{"id":"0c67f37c-19ab-4371-a67d-14ac5a4c1f6a","name":"牛奶","qty":2,"checked":false,...}
💡 说明:API 与 UI 共用同一份数据,脚本写入的条目会实时同步到所有已打开的页面上——这是 OSL 相比「共享备忘录」类方案的核心差异点。
六、适用场景与限制
6.1 适合的场景
- 家庭/合租室友共享购物清单:核心场景,实时协同 + 手机 PWA + 免登录(内网)体验最顺。
- 小团队办公室采购/耗材清单:条目字段够用,CSV 粘贴批量导入(如从表格复制)很实用。
- 多面板并行:家庭一个面板、办公室一个面板、仓库一个面板,同一实例互不干扰。
- 极小主机/NAS 附属服务:约 100 MiB 内存、79 MB 镜像,塞进任何角落。
- 想留在 PostgreSQL 生态又要 MongoDB 协议接口:FerretDB 官方支持是 5.x 的主线。
6.2 限制与风险(选型前必须接受)
- 无内置认证:API 与页面完全开放,安全边界是网络位置。公网直连 = 任何人可改你的清单(5.0.0 已修的 XSS 也侧面提示这一点)。公网暴露必须套反代 + 认证。
- 数量级定位是「家用」:没有分页、没有分片、没有性能调优面;条目量到数千级不构成设计目标。
- 备份方式取决于数据库栈:FerretDB/PostgreSQL 栈用 PostgreSQL 备份链路即可,但官方没有内置导出工具,跨库迁移依赖 MongoDB 协议工具(mongodump/mongoexport 类)。
- 单实例:无集群/高可用方案,停机窗口需接受。
- GitHub 星数 197 属于小众项目:社区规模小,issue 响应依赖作者个人节奏;但代码面窄(server+client 两目录),自我维护门槛低。
- 镜像内 PWA manifest 告警:启动日志会打印一段
manifest.json ENOENT的中间件报错栈,实测不影响功能(PWA 基础功能正常),属于上游已知噪音,可忽略或按《Our Shopping List Docker Compose 部署指南》常见问题一节对照。
七、同类选型对比
对比对象选取原则:都是自托管、都把「购物清单/采购」作为核心或重要能力、都活跃(2025-2026 有发布)。星数为 shields.io GitHub 徽章读取值,版本为各自官方发布页当前稳定版,全部数据查询日期 2026-10-24。
7.1 量化对比总表
| 维度 | Our Shopping List 5.0.0 | Grocy 4.7.1 | KitchenOwl 0.7.10 | Mealie 3.29.0 |
|---|---|---|---|---|
| 定位 | 纯购物清单实时协同 | 家庭 ERP(库存/食谱/购物清单/ chores) | 购物清单 + 记账 + 食谱 | 食谱管理为主,购物清单为附属 |
| GitHub 星数(2026-10-24) | 197(归档冻结) | 9.6k | 3.8k | 14k |
| 当前版本与发布 | 5.0.0(2026-10-19) | 4.7.1(2026-09-04,官网) | 0.7.10(2026-10-24 查) | 3.29.0(2026-10-24 查) |
| 技术栈 | Node.js 22 + Vue 3 + Socket.IO | PHP + SQLite/MySQL | Flask(Python) + Flutter 客户端 | FastAPI(Python) + Vue + SQLite/PostgreSQL |
| 数据库 | MongoDB 协议(FerretDB+PostgreSQL 或 MongoDB) | SQLite(默认)/MySQL | SQLite/PostgreSQL | SQLite(默认)/PostgreSQL |
| 内置认证 | 无 | 有(多用户+权限) | 有(多用户) | 有(多用户) |
| 实时协同 | Socket.IO 秒级推送 | 页面轮询/手动刷新 | 移动端推送同步 | 轮询刷新 |
| 中文界面 | 有(12 语言含 zh) | 有 | 有 | 有 |
| 部署体量(内存实测/官网口径) | 三服务约 100 MiB | 单服务,约 50~100 MiB 级 | 单服务约 100 MiB 级 | 单服务约 200~500 MiB 级 |
| 许可证 | AGPL-3.0 | MIT(部分商业功能付费) | AGPL-3.0 | AGPL-3.0 |
| 维护方 | 个人(nanawel) | 个人(Bernd Bestel)+ 社区 | 个人(TomBursch)+ 社区 | 社区(mealie-recipes org) |
| 代码托管 | Codeberg(GitHub 已归档) | GitHub | GitHub | GitHub |
表格解读:星数差距(197 vs 9.6k/14k)反映的是社区规模差距,不是能力差距——OSL 的用户面就是「只要一张共享清单」的人;Grocy/Mealie 的购物清单只是其庞大功能的一角。若只需要清单本身,上表前四行决定了 OSL 的轻量与专注优势。
7.2 版本节奏量化(近 15 个月发布计数)
| 项目 | 发布次数(2025-07 ~ 2026-10) | 观察到的节奏 |
|---|---|---|
| OSL | 11 个 tag(4.0.0→5.0.0) | 1~2 月一个小版本,含 1 次安全修复 |
| Grocy | 官网 changelog 实查为持续更新(4.4→4.7.1) | 2~3 个月一个中版本 |
| KitchenOwl | 官方 releases 持续(0.6.x→0.7.10) | 数周一小版 |
| Mealie | 官方 releases 高频(2.x→3.29.0) | 高频滚动 |
解读:四者都活着,OSL 的发布密度不落后;差异在响应面——大项目有社区 PR 与安全团队,OSL 只有作者本人,重大问题(如 5.0.0 的 XSS)依赖单点响应。
7.3 兼容矩阵(自托管关键路径)
| 兼容项 | OSL 5.0.0 | 说明 |
|---|---|---|
| 浏览器 | 现代浏览器 + PWA | 实测桌面 Chrome 与移动端可加主屏 |
| 数据库 | FerretDB 2.x + PostgreSQL 17;MongoDB 4.x→7.x | 官方两套 compose 均提供;Mongo→FerretDB 有官方迁移文档 |
| 反向代理 | Apache / Nginx(官方给出含 WebSocket 的配置片段) | 必须代理 WebSocket 升级头,否则实时同步失效 |
| HTTPS | 由反代卸载,应用本身不提供 TLS | ENABLE_TLS 等变量不在 5.x README 配置面内 |
| 架构 | 镜像为 linux/amd64 为主 | 小众项目,ARM 需自行构建(源码提供 Dockerfile) |
7.4 「如果…则…」选型建议
- 只要一张全家共享的购物清单、设备都是手机浏览器、部署在家庭内网 → OSL:最轻、最专注、实时同步体验最好。
- 需要库存保质期、消耗品管理、家务安排,购物清单只是配套 → Grocy:功能全面但学习成本与界面复杂度显著更高。
- 清单+记账+食谱一体,且家人主力是手机 App 体验 → KitchenOwl:Flutter 客户端体验最好,但要接受更大的部署面。
- 主需求是食谱库,清单是从食谱一键生成 → Mealie:食谱生态最强。
- 需要公网暴露且不想维护反代认证 → 排除 OSL(无认证),选 Grocy/KitchenOwl/Mealie。
- 已有 MongoDB 运维体系 → OSL 遗留栈可复用;否则一律走 OSL + FerretDB/PostgreSQL。
八、参考链接
- Codeberg 主仓库(当前唯一活跃仓库):https://codeberg.org/nanawel/our-shopping-list
- 5.0.0 Release(FerretDB 正式支持、XSS 修复):https://codeberg.org/nanawel/our-shopping-list/releases/tag/5.0.0
- GitHub 归档仓库(只读,2026-08-03):https://github.com/nanawel/our-shopping-list
- 官方镜像(Docker Hub):https://hub.docker.com/r/ourshoppinglist/our-shopping-list
- 星数徽章取数(2026-10-24):https://img.shields.io/github/stars/nanawel/our-shopping-list
- Grocy 官网(版本与定位):https://grocy.info/
- KitchenOwl 仓库:https://github.com/tombursch/kitchenowl
- Mealie 文档站:https://mealie.io/
本专栏其余篇目:部署落地见《Our Shopping List Docker Compose 部署指南》;环境变量逐项说明见《Our Shopping List 5.0.0 配置参数详解》;接口与实时通道详见《Our Shopping List 5.0.0 API 使用详解》。