Geeftlist 介绍与选型指南
Geeftlist(AGPL-3.0,PHP/Fat-Free + MariaDB + Redis)开源礼品清单协作平台的介绍与选型指南:项目背景、核心架构、功能特性、快速上手与同类对比,信息溯源自官方仓库(查询日期 2026-10-28)。
Geeftlist 介绍与选型指南
目标:面向"家庭/朋友圈礼品清单协作"场景,介绍开源自托管平台 Geeftlist 的定位、架构、功能与选型对比,帮助读者判断它是否适合作为家庭礼物协调方案。本文所有项目信息均溯源自官方代码仓库与文档,查询日期为 2026-10-28。
一、环境信息
本文信息采集与结论核验所用的环境如下:
- 信息溯源对象:Geeftlist 官方代码仓库
codeberg.org/nanawel/geeftlist(PHP 项目,AGPL-3.0 许可证) - 官方网站:https://www.geeftlist.com(官方托管实例)
- 当前最新版本:0.51.2(官方仓库 tag,提交日期 2026-10-23)
- 技术栈(溯源自仓库
src/composer.json、support/docker/production/docker-compose.yml,查询日期 2026-10-28):- 服务端:PHP ≥ 8.1(官方构建使用 PHP 8.3)+ Fat-Free Framework 3.8.2
- 数据库:MariaDB(生产编排默认 10.5 系列,utf8mb4 字符集)
- 缓存:Redis(生产编排默认 6-alpine 系列)
- Web 服务:Apache 2(mod_rewrite/deflate/expires)
- 前端构建:Node.js 20 + Yarn(Foundation 样式框架 + Gulp 构建链)
- 本系列配套实测环境:Ubuntu 22.04 服务器单机部署(Apache + PHP 8.3 + MariaDB 10.6 + Redis 6.0),见《Ubuntu 22.04 安装 Geeftlist 0.51.2 指南》。
💡 说明:Geeftlist 的官方仓库位于 Codeberg(codeberg.org),而非 GitHub。网络上部分镜像/聚合站点将其归属到 GitHub 路径下均已失效,安装时应以 Codeberg 仓库为准。
二、软件概述
Geeftlist 是一个自托管的协作式礼品清单(wishlist/gift list)管理 Web 应用,目标是解决"家庭内部互送礼物的协调"问题:每位成员维护自己的礼物愿望,其他人可以私密地认领(reserve)这些愿望,避免重复购买,也不会让收礼人提前"剧透"。
项目背景(溯源自官方 README,查询日期 2026-10-28):作者自述 Geeftlist 起源于其家庭圣诞节送礼协调的复杂性——每个家庭成员给所有人送礼,传统电话/邮件协调既慢又容易出错。项目从 2019 年前后开始设计(早期基于 PHP 的 Fat-Free Framework 做服务端渲染),以闭源形式运营多年后,"在开发 8 年、上线运行 7 年后,源代码终于公开"(README 原文:After 8 years of development and 7 years of being live, the source code has finally been published)。也就是说,它不是一个"周末项目",而是一个先在生产环境长期运行、后开源的成熟应用。
核心关键词:
- 协作礼物清单:围绕"家庭(family)"组织成员,成员之间互为"受赠人(geeftee)"与"送礼人(geefter)";
- 私密认领:礼物一旦被认领,其他成员看不到认领状态,收礼人本人也看不到谁认领了自己的愿望;
- 自托管:代码 AGPL-3.0 开源,官方同时提供在线实例 www.geeftlist.com,也支持部署到自己的服务器。
💡 技术拓展:开源礼品/愿望清单类自托管应用常见两类许可证——MIT/Apache 类宽松许可(如 wishlist、Family Wishlist)与 AGPL/GPL 类同源许可(如 Geeftlist 的 AGPL-3.0、wishthis 的 AGPL-3.0)。宽松许可允许闭源二次分发,AGPL 则要求"通过网络提供服务"时同样开放源代码,对商用 SaaS 改造更严格。Geeftlist 选择 AGPL-3.0,与其"官方在线实例 + 开源自托管"双轨运营的模式相匹配:第三方若基于它做在线服务,必须同样开源。
三、核心架构
Geeftlist 采用经典的"单体 PHP Web 应用 + 关系型数据库 + 缓存"三层架构,无微服务、无消息队列,部署面很小。以下组件构成与依赖版本均溯源自官方仓库(src/composer.json、src/etc/*.ini、support/docker/production/docker-compose.yml,查询日期 2026-10-28)。
浏览器 ──HTTP(S)──▶ Apache(mod_rewrite) ──▶ PHP 应用(Fat-Free 框架路由)
│
├──▶ MariaDB(业务数据:用户/家庭/清单/礼物/预订/通知)
└──▶ Redis(会话缓存 / F3 框架缓存 / OliveOil 缓存池)
定时任务 ──HTTP 调用 /cron/run──▶ 应用内置 Cron 调度器(延迟通知、孤儿图片清理等)
监控端 ──▶ /system/healthcheck(Prometheus 指标端点)
分层说明:
| 层 | 组件 | 说明 |
|---|---|---|
| 接入层 | Apache 2 + mod_rewrite | 官方打包形态内置 Apache,DocumentRoot 指向应用 src/pub/,由 .htaccess 将所有非静态请求重写到前端控制器 index.php(API 请求重写到 api.php) |
| 应用层 | PHP ≥ 8.1 + Fat-Free Framework 3.8.2 | 模块化单体:app/code/Geeftlist(业务)+ app/code/OliveOil(自研框架层,DI 容器、事件管理、资源模型),依赖 symfony/mailer(发信)、monolog(日志)、laminas-db(数据库访问)、lcobucci/jwt(API 令牌) |
| 数据层 | MariaDB | utf8mb4 字符集,核心表包括 geefter(用户)、geeftee(受赠人)、family/family_geeftee(家庭与成员关系)、giftlist(清单)、gift(礼物)、reservation(认领/购买记录)、通知与审计等约 28 张表(实测安装后表数量) |
| 缓存层 | Redis | 会话存储、框架缓存与业务缓存池;实测为硬依赖——停止 Redis 后首页与 healthcheck 立即返回 500(本文实测) |
| 任务层 | Cron 调度器 | 应用内置 cron 事件(延迟通知发送、过期数据清理、索引重建等),部署形态需由外部定时器周期性请求 BASE_URL/cron/run 触发 |
| 可观测 | Prometheus 指标 | GET /system/healthcheck 输出 Prometheus 文本格式指标(收集耗时、cron 最近运行时间等),并受 IP 白名单参数控制(实测) |
💡 技术拓展:PHP 应用的会话与缓存后端常见选择有「文件」「Redis」「Memcached」三类。文件方式零依赖但多机共享困难;Redis 支持过期时间与丰富的数据结构,Memcached 更简单但功能少。Geeftlist 生产形态实际采用 Redis(
RESOURCE_CONFIG.redis_cache.*参数组),并同时把 PHP 会话落到可挂载的var/sessions/目录,兼顾缓存性能与会话文件的可运维性。
四、功能特性
以下功能清单综合自官方 README、HISTORY.md 变更记录与本文实测核验(实测环境见文首),标注「实测」的条目均在 Ubuntu 22.04 + Geeftlist 0.51.2 环境验证通过。
| 功能域 | 能力 | 依据 |
|---|---|---|
| 账户体系 | 用户注册(可开关)、邮箱验证、独立 API Token、密码最小长度约束 | composer/源码 + 实测 |
| 家庭协作 | 创建/搜索家庭、加入审批(membership request)、成员角色、geeftee 档案 | 实测:注册→申请入伙→审批全链路通过 |
| 礼物管理 | 礼物创建(名称/描述/估价/优先级 0-300)、所属清单、多人受赠(geeftee_ids)、图片上传 | 实测:gift/save 创建礼物成功 |
| 清单管理 | 多清单(giftlist)、私有/公开可见性、按人查看"我的/亲属的"礼物 | 源码路由 + 实测清单创建 |
| 认领与购买 | 私密认领(reservation)、购买标记(purchase)、取消认领、陈旧认领提醒 | 实测:bob 认领 admin 的礼物入库成功 |
| 讨论 | 礼物级讨论区(@提及、邮件通知)、评论软删除 | HISTORY.md + 源码 |
| 通知体系 | 站内 + 邮件通知、延迟合并发送(NOTIFICATION_DEFER_DELAY/MAX_COUNT)、SMTP 可配置 | app.ini 参数组 + 实测参数读取 |
| 搜索 | 礼物搜索(0.50.0 引入)、家庭浏览/搜索 | HISTORY.md + 实测 /family_search/grid |
| API | JSON:API 风格 REST API(/api/ 前缀,JWT 认证,账户注册/资源读写) | routing-api.ini + composer(neomerx/json-api 等) |
| 运维 | Prometheus 健康检查端点、维护模式(503)、系统信息/配置导出命令、索引重建、缓存清理 | 实测:system/startMaintenance 后首页 503、healthcheck 输出指标 |
| 国际化 | 多语言(默认 en-US/fr-FR,词典文件可同步生成)、时区参数 | local.ini.sample + 源码 |
关键取舍:Geeftlist 的功能收敛在"礼物协调"一件事上,不提供电商比价、注册表单(registry)式礼物池、活动签到等扩展能力;这也是它与其他通用清单类工具最显著的差异点。
五、快速开始(最小可用示例)
本节给出从零到"可用实例"的最短路径概览,方便评估体量;完整分步过程(含排障实录)见《Ubuntu 22.04 安装 Geeftlist 0.51.2 指南》。以下命令在本文实测环境(Ubuntu 22.04、PHP 8.3、MariaDB 10.6、Redis 6.0)逐条验证过。
- 准备运行依赖(数据库、缓存、Web 服务与 PHP 扩展):
sudo apt-get install -y apache2 mariadb-server redis-server \
php8.3 php8.3-intl php8.3-gd php8.3-mysql php8.3-curl \
php8.3-xml php8.3-mbstring php8.3-zip php8.3-redis
- 获取 0.51.2 源码并安装 PHP 依赖:
sudo mkdir -p /var/www && cd /var/www
sudo git clone --branch 0.51.2 --depth 1 https://codeberg.org/nanawel/geeftlist.git webapp
cd webapp/src
sudo composer install --no-dev --optimize-autoloader --no-interaction
实测回显(输出节选,实测首尾):
Generating optimized autoload files
Class OliveOil\Core\Test\Model\ResourceModel\Db\SetupTest located in ./app/code/OliveOil/Core/Test/Model/Resource/Db/SetupTest.php does not comply with psr-4 autoloading standard. Skipping.
> test ! -x vendor/bin/phpcs || vendor/bin/phpcs --config-set installed_paths vendor/phpcompatibility/php-compatibility
- 建库并初始化(先在 MariaDB 中创建
geeftlist库与用户,应用侧写入src/etc/local.ini指向数据库与 Redis,然后执行安装命令):
cd /var/www/webapp
sudo -u www-data php8.3 ./src/console setup/install
实测回显(输出节选,实测首尾):
2026-10-28T06:38:38+00:00 [20 MB] INFO - 0.27.0 => 0.36.0 []
2026-10-28T06:38:38+00:00 [20 MB] DEBUG Running setup script app/code/Geeftlist/setup/data/upgrade-0.27.0-0.36.0.php... []
2026-10-28T06:38:38+00:00 [20 MB] INFO Upgrade finished successfully []
2026-10-28T06:38:38+00:00 [20 MB] INFO Installation finished successfully []
Success.
- 验证健康检查端点:
curl -s http://127.0.0.1/system/healthcheck | head -4
实测回显:
# HELP geeftlist_collect_time
# TYPE geeftlist_collect_time gauge
geeftlist_collect_time 0.50676703453064
# HELP geeftlist_cron_last_run
- 浏览器访问站点,注册首个用户(示例演示账号:用户名
admin、邮箱admin@example.com、密码q1w2e3r4),即可创建家庭、清单并开始添加礼物。
⚠️ 注意:首次注册需在站点可访问后通过 Web 页面完成;若希望跳过邮件验证(无 SMTP 服务器时),需在配置中将
NO_CONFIRMATION_EMAIL设为1、EMAIL_ENABLED设为0,否则新账户需等待验证邮件。参数含义与实测行为见《Geeftlist 0.51.2 配置参数详解》。
六、适用场景与限制
适用场景:
- 家庭节日送礼协调:多位成员互送礼、需要防重复购买与"惊喜保密",这是 Geeftlist 的原生场景(作者家庭圣诞送礼的真实痛点驱动);
- 朋友圈/小社群礼物互助:通过家庭(family)机制组织 3~30 人规模的固定圈子,成员各自维护愿望;
- 隐私敏感的自托管需求:不想把家庭礼物计划交给商业 SaaS(其数据常与营销画像关联),希望在自有服务器上持有数据;
- 需要 API 集成的极客家庭:JSON:API + JWT 的 REST API 便于自建自动化(如定期导出、与家庭自动化联动)。
限制(官方现状,查询日期 2026-10-28):
- 官方仅支持一种官方打包部署形态(生产编排文件),源码直装需要自行承担依赖与权限配置——本系列实测已验证源码直装路径可行,见《Ubuntu 22.04 安装 Geeftlist 0.51.2 指南》;
- 无管理后台:README 明确将 admin interface 列入未来路线图,当前实例级管理依赖命令行(
system/*、setup/*命令族,见《Geeftlist 0.51.2 常用 CLI 命令与工具详解》); - 定时任务需要外部触发:官方打包形态不内置定时器,需在宿主上配置 cron 定期请求
/cron/run; - 社区规模小:Codeberg 仓库 star 数为个位数(查询日期 2026-10-28 时为 4),issues 活跃度低,遇到问题主要靠自行读源码;
- 版本节奏慢但稳定:2024 年 4 个 minor 版本、2025 年 2 个、2026 年至今 3 个,均为向后兼容的升级脚本式演进。
七、同类选型对比
自托管礼品/愿望清单属于长尾小众品类,没有数据库/消息队列那种"大厂林立"的格局。下表选取可证实的同类开源项目(数据均通过各自代码仓库公开信息核实,查询日期 2026-10-28)与 Geeftlist 对比;同时列出商业托管服务作为品类参照(不计入开源对比)。
| 项目 | 许可证 | 技术栈 | 仓库活跃度(查询日 2026-10-28) | 协作模型 | 与 Geeftlist 的关键差异 |
|---|---|---|---|---|---|
| Geeftlist | AGPL-3.0 | PHP 8.1+ / Fat-Free / MariaDB / Redis | Codeberg 主仓,4 star、3 open issue、2026-10-23 仍有提交;8 年生产运行史 | 家庭制、私密认领、防重复购买、通知体系完整 | 本文主角;功能最完整、单机资源占用极低,但社区小 |
| cmintey/wishlist | MIT | TypeScript(Node 全栈) | GitHub 674 star | 单清单 + 共享分组,认领隐藏 | 社区最活跃、上手快;但无"家庭/受赠人"多人关系模型,更偏"个人清单分享" |
| wishthis | AGPL-3.0 | PHP / JavaScript | GitHub 310 star | 多用户清单 + 分享链接 | 形态接近传统 wishlist 站点;无家庭审批、无私密认领语义,协作深度弱于 Geeftlist |
| aunefyren/poenskelisten | GPL-3.0 | Go | GitHub 213 star | 分组 + 清单共享 | Go 单二进制部署最简单;功能面窄(基础清单共享),无讨论/通知体系 |
| JonReed/cloudflare-family-wishlist | MIT | TypeScript(Cloudflare Workers 全栈) | GitHub 1 star,2026-08 新建 | 家庭私有清单 | 依赖 Cloudflare 免费套餐零成本运行;绑定单一云平台,不适用于自有服务器场景 |
| 商业托管参照:Elfster、DrawNames 等 | 闭源 SaaS | 托管服务 | —— | 注册即用 | 免部署但有广告与数据画像顾虑,不提供数据主权——这正是选择自托管方案的核心动机 |
💡 说明:星标数仅反映社区关注度,不等于成熟度。Geeftlist 的 star 数远低于 cmintey/wishlist,但它有"闭源运营 7 年后开源"的独特履历——功能是按真实家庭多年使用打磨的,而非新创项目。选型时建议把"功能完整度 × 部署复杂度 × 社区支持"放在一起权衡。
选型建议(按"如果……则……"表述):
- 如果你要最小部署成本(一条命令跑起来的单二进制)→ 优先 poenskelisten(Go);
- 如果你要活跃社区 + 通用清单分享,且没有"家庭审批/私密认领"诉求 → 选 cmintey/wishlist;
- 如果你的服务器只能跑 PHP + MariaDB(与现有 LAMP 环境合并)→ Geeftlist 或 wishthis 均可,需要家庭协作与通知体系选 Geeftlist;
- 如果你想零成本托管但接受平台绑定 → cloudflare-family-wishlist;
- 如果你不愿自己运维且不介意商业服务 → Elfster/DrawNames 类 SaaS;
- 如果你的诉求就是"家庭礼物的防重复购买 + 惊喜保密 + 自托管" → Geeftlist 是当前功能覆盖最完整的选择,本系列其余三篇提供完整的部署、配置与运维实践。
八、参考链接
- 官方网站(在线实例):https://www.geeftlist.com
- 官方代码仓库(Codeberg):https://codeberg.org/nanawel/geeftlist (版本、许可证、HISTORY.md 均溯源自此,查询日期 2026-10-28)
- 官方生产部署文档:https://codeberg.org/nanawel/geeftlist/src/branch/main/support/docker/production/README.md
- Fat-Free Framework:https://fatfreeframework.com/
- 站内配套文档:
- 《Ubuntu 22.04 安装 Geeftlist 0.51.2 指南》——源码直装全流程与排障实录
- 《Geeftlist 0.51.2 配置参数详解》——local.ini 参数逐项实测
- 《Geeftlist 0.51.2 常用 CLI 命令与工具详解》——console 命令族与备份恢复
- 《MariaDB 11.8 配置参数详解》——数据层 MariaDB 的参数调优参考
- 《Ubuntu 22.04 安装 Redis 8 指南》——缓存层 Redis 的安装与部署参考