Geeftlist 介绍与选型指南

Geeftlist(AGPL-3.0,PHP/Fat-Free + MariaDB + Redis)开源礼品清单协作平台的介绍与选型指南:项目背景、核心架构、功能特性、快速上手与同类对比,信息溯源自官方仓库(查询日期 2026-10-28)。

GeeftlistGeeftlist2026/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 令牌)
数据层MariaDButf8mb4 字符集,核心表包括 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
APIJSON: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)逐条验证过。

  1. 准备运行依赖(数据库、缓存、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
  1. 获取 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
  1. 建库并初始化(先在 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.
  1. 验证健康检查端点:
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 
  1. 浏览器访问站点,注册首个用户(示例演示账号:用户名 admin、邮箱 admin@example.com、密码 q1w2e3r4),即可创建家庭、清单并开始添加礼物。

⚠️ 注意:首次注册需在站点可访问后通过 Web 页面完成;若希望跳过邮件验证(无 SMTP 服务器时),需在配置中将 NO_CONFIRMATION_EMAIL 设为 1、EMAIL_ENABLED 设为 0,否则新账户需等待验证邮件。参数含义与实测行为见《Geeftlist 0.51.2 配置参数详解》。

六、适用场景与限制

适用场景:

  1. 家庭节日送礼协调:多位成员互送礼、需要防重复购买与"惊喜保密",这是 Geeftlist 的原生场景(作者家庭圣诞送礼的真实痛点驱动);
  2. 朋友圈/小社群礼物互助:通过家庭(family)机制组织 3~30 人规模的固定圈子,成员各自维护愿望;
  3. 隐私敏感的自托管需求:不想把家庭礼物计划交给商业 SaaS(其数据常与营销画像关联),希望在自有服务器上持有数据;
  4. 需要 API 集成的极客家庭:JSON:API + JWT 的 REST API 便于自建自动化(如定期导出、与家庭自动化联动)。

限制(官方现状,查询日期 2026-10-28):

  1. 官方仅支持一种官方打包部署形态(生产编排文件),源码直装需要自行承担依赖与权限配置——本系列实测已验证源码直装路径可行,见《Ubuntu 22.04 安装 Geeftlist 0.51.2 指南》;
  2. 无管理后台:README 明确将 admin interface 列入未来路线图,当前实例级管理依赖命令行(system/*、setup/* 命令族,见《Geeftlist 0.51.2 常用 CLI 命令与工具详解》);
  3. 定时任务需要外部触发:官方打包形态不内置定时器,需在宿主上配置 cron 定期请求 /cron/run;
  4. 社区规模小:Codeberg 仓库 star 数为个位数(查询日期 2026-10-28 时为 4),issues 活跃度低,遇到问题主要靠自行读源码;
  5. 版本节奏慢但稳定:2024 年 4 个 minor 版本、2025 年 2 个、2026 年至今 3 个,均为向后兼容的升级脚本式演进。

七、同类选型对比

自托管礼品/愿望清单属于长尾小众品类,没有数据库/消息队列那种"大厂林立"的格局。下表选取可证实的同类开源项目(数据均通过各自代码仓库公开信息核实,查询日期 2026-10-28)与 Geeftlist 对比;同时列出商业托管服务作为品类参照(不计入开源对比)。

项目许可证技术栈仓库活跃度(查询日 2026-10-28)协作模型与 Geeftlist 的关键差异
GeeftlistAGPL-3.0PHP 8.1+ / Fat-Free / MariaDB / RedisCodeberg 主仓,4 star、3 open issue、2026-10-23 仍有提交;8 年生产运行史家庭制、私密认领、防重复购买、通知体系完整本文主角;功能最完整、单机资源占用极低,但社区小
cmintey/wishlistMITTypeScript(Node 全栈)GitHub 674 star单清单 + 共享分组,认领隐藏社区最活跃、上手快;但无"家庭/受赠人"多人关系模型,更偏"个人清单分享"
wishthisAGPL-3.0PHP / JavaScriptGitHub 310 star多用户清单 + 分享链接形态接近传统 wishlist 站点;无家庭审批、无私密认领语义,协作深度弱于 Geeftlist
aunefyren/poenskelistenGPL-3.0GoGitHub 213 star分组 + 清单共享Go 单二进制部署最简单;功能面窄(基础清单共享),无讨论/通知体系
JonReed/cloudflare-family-wishlistMITTypeScript(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 是当前功能覆盖最完整的选择,本系列其余三篇提供完整的部署、配置与运维实践。

八、参考链接