Gancio 介绍与选型指南

Gancio 1.28.2 认知篇:自托管社区活动发布平台的定位、Node.js 架构、功能特性与快速上手实测,并与 DAViCal/Baïkal/Radicale 等日历同步方案做量化选型对比。

GancioGancioNodejsDocker日历自托管2026/11/02

Gancio 介绍与选型指南

目标:本文基于运行中的 Gancio 1.28.2 实例(Docker Compose 部署、Node.js v20.19.6、SQLite 后端)的逐条实测取证,并结合官网、Framagit 仓库、发行包内 CHANGELOG 与 Docker Hub 的联网溯源(查询日期 2026-11-01),梳理 Gancio 的产品定位、架构、功能特性与发布节奏,并与 DAViCal、Baïkal、Radicale 等日历类自托管方案做选型对比,帮助读者判断是否选用 Gancio。

一、环境信息

本文取证渠道与版本基线如下(查询日期均为 2026-11-01):

  • 本地实测载体:运行中的 Gancio 实例,应用版本 v1.28.2,运行时 Node.js v20.19.6(gancio --help 回显),服务监听 13120 端口、本机映射 8149 端口;数据目录 /opt/gancio/data(内含 SQLite 库 gancio.sqlite 与配置文件 config.json)。
  • 联网溯源渠道:
    • 官网 https://gancio.org/(标题与 tagline,经代理访问实测)
    • 上游仓库 Framagit API les/gancio(star/fork/活跃度/默认分支)
    • 部署实例程序目录 /home/node/CHANGELOG.md(1.28.x 发布日期与 1.x 停维声明)、/home/node/LICENSE(AGPL-3.0)、/home/node/locales/(语言清单实测计数)、/home/node/gancio_plugins/(内置插件清单)
    • Docker Hub API cisti/gancio(pull 数、tag 列表与日期)
  • 版本基线:
组件版本来源
Gancio1.28.2(2025-12-15,1.x 最后一版)发行包内 CHANGELOG.md
Node.js 运行时v20.19.6gancio --help 回显
官方发行cisti/gancio:1.28.2(解压约 898 MB)部署实例实测
2.0 开发线2.0.0-beta.8(2026-10-23 发布)Docker Hub tags API
DAViCal1.1.13站内已收官文档
Baïkal0.10.1站内已收官文档
Radicale3.9站内已收官文档

⚠️ 网络说明:溯源当日宿主机直连 hub.docker.com 与 framagit.org 超时不通,改用代理 http://192.168.1.72:7897 后经 curl -x 实测可用;gancio.org 同样仅代理可达。

二、软件概述

2.1 Gancio 是什么

Gancio(意大利语「锚」)是一款面向本地社区的活动事件发布平台,官网 tagline 为 "A shared agenda for local communities"(来源:官网首页,查询日期 2026-11-01)。它不是给个人做多设备日历同步的服务器,而是给协会、社区中心、俱乐部这类组织做一个公开活动日历网站:成员或访客提交活动(标题、时间、地点、标签、图片),管理员/编辑审核后在首页日历上公开展示,同时通过 RSS、iCalendar(ICS)feed 对外输出订阅,并可接入 Fediverse(Mastodon 等)让活动被转发。

技术上 Gancio 是 Node.js 单体应用:Express 提供 REST API 与联邦端点,Nuxt(Vue SSR)渲染前端页面,Sequelize ORM 落 SQLite/PostgreSQL/MSSQL,ActivityPub 协议模块实现与 Fediverse 互操作。许可证为 AGPL-3.0(来源:部署实例程序目录 /home/node/LICENSE 实测首部),上游托管在 Framagit les/gancio(GitHub 上的 lesion/gancio 仅为同步副本、非主仓)。

💡 技术拓展:自托管「日历」类软件其实分两个物种,选型前务必分清——

物种核心协议数据流向代表
日历同步服务器CalDAV/CardDAV(读写)个人日历在多客户端间双向同步DAViCal、Baïkal、Radicale
活动发布平台HTTP 网站 + RSS/ICS 只读订阅 + ActivityPub组织者→公众的单向发布与聚合Gancio、Luma

本文的 Gancio 属于后者:它没有 CalDAV 读写接口,只能被日历客户端只读订阅 ICS feed。

2.2 版本与社区活跃度(量化)

维度数据来源
上游仓库Framagit les/gancio,66 stars / 85 forks,2019-08-07 创建Framagit API,2026-11-01
最近活动2026-11-01 仍有提交活动Framagit API last_activity_at
发布节奏1.x 约每月一版(1.9.0 2024-08 → 1.28.2 2025-12)Docker Hub tags + CHANGELOG
1.x 状态1.28.0 起声明「1.x 最后一版」,功能开发转向 main 分支 2.0发行包内 CHANGELOG.md
2.0 进度2.0.0-beta.8(2026-10-23),beta 线活跃Docker Hub tags API
分发渠道Docker Hub cisti/gancio 累计 pull 48,380Docker Hub API
多语言44 个 locale 文件(含 zh.json 中文)发行包内 locales/ 实测计数

一句话解读:项目活跃但处于 1.x→2.0 换代期——1.28.2 是 1.x 末代稳定版(本文基线),2.0 尚在 beta,生产部署选 1.28.x,新功能观望 2.0。

三、核心架构

3.1 运行时形态

Gancio 是单进程 Node.js 应用(/usr/local/bin/gancio → server/cli.js,默认子命令 start),进程内同时承载四层:

  1. Nuxt SSR 前端:pages/index.vue 起的服务端渲染页面(日历首页、活动详情、管理后台);
  2. Express API:/api 前缀的 REST 路由(事件/地点/标签/集合/用户/设置/导出等,路由总表实测约 70 条);
  3. 联邦模块:/federation(ActivityPub inbox/outbox)、/.well-known(webfinger、nodeinfo 2.0/2.1);
  4. 任务管理器:进程内定时器,10 秒轮询一次,实测启动日志注册了 5 个周期任务——
ℹ [TASK] Add CREATE_RECURRENT_EVENT (30分钟)
ℹ [TASK] Add CLEAN_UNUSED_PLACES (1天)
ℹ [TASK] Add CLEAN_UNUSED_TAGS (1天和1分钟)
ℹ [TASK] Add CLEAN_FEDIVERSE_PAST_EVENT (6小时和5分钟)
ℹ [TASK] Add CLEAN_FEDIVERSE_AP_USERS (1天和10分钟)
ℹ START TASK MANAGER WITH LOOP INTERVAL OF 10 seconds

(来源:服务启动日志实测,docker compose logs 可见。)

3.2 配置三层结构(实测归纳)

Gancio 的「配置」分散在三层,这是排错时最容易踩坑的架构事实:

层载体管什么生效方式
环境变量GANCIO_DATA/HOST/PORT、GANCIO_DB_*、GANCIO_PROXY_*数据目录、监听地址、数据库连接、出网代理首次启动生成 config.json
运行时配置文件data/config.json端口、日志级别/路径、DB 连接参数、上传目录改后重启进程
站点设置数据库 settings 表(实测 47 个键)标题/语言/时区/注册开关/匿名投稿/联邦开关/主题色/SMTP/插件管理界面或 gancio settings set,改后需重启

⚠️ 实测陷阱:社区流传的 compose 示例里常见的 GANCIO_URL、GANCIO_NAME、GANCIO_LOCALE、GANCIO_TIMEZONE、GANCIO_EMAIL、GANCIO_ORIGIN 在 1.28.2 全部源码中无任何引用(grep -rn "process.env.GANCIO" server/ 实测仅返回 DATA/HOST/PORT/DB_/PROXY_ 17 个变量),站点名称、语言、时区实际存在数据库 settings 表里,用这些环境变量设置不会生效。

3.3 数据与扩展

  • 数据库:Sequelize 多方言。SQLite 为默认(db.dialect=sqlite, storage=./gancio.sqlite,并针对 SQLITE_BUSY 配置了最多 15 次重试,实测 config.json 可见);生产推荐 PostgreSQL(CHANGELOG 中多处 postgres 修复);代码另有 MariaDB JSON 修正逻辑,官方文档支持 MSSQL。
  • 插件体系:发行包内置 5 个插件(实测 gancio_plugins/:bluesky-bridge、discord-bridge、feed、telegram-bridge、webhook),默认全部 enable=false,在管理界面或 settings 表 plugin_<名> 键开启;外部插件放 data/plugins/。
  • 认证:内置 OAuth2 授权服务器(oauth2orize + passport),前端与第三方都用 POST /oauth/login(password grant,公开 client_id=self)换 Bearer token,实测可用。
  • 存储目录:data/uploads(活动图片+缩略图)、data/logs(winston 按天滚动)、data/user_locale(用户自定义文案)。

四、功能特性

以下特性均在 1.28.2 实测或从 settings/路由表实证:

功能域实测要点
活动发布支持多日期活动(allow_multidate_event)、无结束时间活动、线上活动(allow_online_event)、重复活动(allow_recurrent_event,默认关);时间字段为 Unix 秒(实测传毫秒被拒:"are you sure?")
地点与标签地点自动按名称去重复用(实测同名地点返回同一 place.id);标签数组必填为 JSON 数组;可选 Nominatim/Photon 地理编码与 OSM 瓦片(allow_geolocation 默认关)
集合(Collection)按标签/地点等过滤器组合出子日历页面,/api/collections、/feed/:format/collection/:name 实测存在
审核与角色admin/editor/user 三角色;未确认队列 /api/event/unconfirmed、举报/评论消息、禁用作者等路由实证
对外输出/feed/rss、/feed/ics 实测返回标准 RSS 2.0 与 ICS(X-PUBLISHED-TTL:PT1H);/api/export/json 实测返回全量事件 JSON;支持按 tag/place/collection 出 feed
ICS 导入POST /api/ics-import(文件)与 /api/ics-import/url 路由实证
Fediverse 联邦enable_federation=true;nodeinfo 实测 protocols:["activitypub"]、outbound:["rss2.0"]、openRegistrations:true;应用 Actor 为 Application 型(实测 /federation/u/relay 返回 Mastodon 兼容 toot: 命名空间);可信实例/屏蔽/关注管理路由实证
匿名投稿allow_anon_event=true(默认开),匿名事件进入待确认队列
界面与主题深/浅色主题色板、logo/头图/兜底图上传、custom_js/custom_css、页脚链接自定义(settings 实测键)
多语言44 个 locale(含中文 zh.json),instance_locale=zh 实测界面为中文
通知SMTP 设置与测试端点(/api/settings/smtp、test_smtp)实证;admin_email、to_notify 字段实证

五、快速开始(最小可用示例)

本节给出「一条 compose + 一次初始化」的最小路径,完整部署(发行版选型、持久化、Nginx 反代、升级)见 《Gancio 1.28.2 Docker Compose 部署指南》。

5.1 起一个最小实例

# docker-compose.yml(最小可用,SQLite)
services:
  gancio:
    image: cisti/gancio:1.28.2
    restart: always
    environment:
      - GANCIO_DB_DIALECT=sqlite
      - GANCIO_DB_STORAGE=./gancio.sqlite
    volumes:
      - ./data:/home/node/data
    ports:
      - "8149:13120"
docker compose up -d

5.2 初始化与验证(实测回显)

首次访问 http://127.0.0.1:8149/ 进入设置向导,确认后应用会**自动生成 admin 账号(用户名固定为 admin,随机密码,界面一次性展示)**并自动重启服务拉起。实测各端点:

curl -s http://127.0.0.1:8149/api/ping
OK
curl -s -X POST http://127.0.0.1:8149/oauth/login \
  -d 'grant_type=password&client_id=self&username=admin&password=q1w2e3r4'
{"access_token":"qq5gf60z5hbbjyhly6nug0c0t6o1bdgi","refresh_token":"72y3gzrsdz5pjddzl6qdgkd6lyes0nyv","username":"admin","token_type":"Bearer"}

⚠️ 实测两个易错点:登录端点是 /oauth/login 而不是 /api/login;请求体必须是 application/x-www-form-urlencoded 且带 client_id=self,发 JSON 或缺 client 一律 Unauthorized。若向导随机密码未留存,用 gancio users reset-password admin 或重建账号(见运维篇)。

curl -s -X POST http://127.0.0.1:8149/api/event \
  -H "Authorization: Bearer <access_token>" -H 'Content-Type: application/json' \
  -d '{"title":"取证测试活动","start_datetime":1795370400,"place_name":"测试地点","place_address":"测试地址 1 号","tags":["测试"],"confirmed":true}'
{"id":2,"title":"取证测试活动","start_datetime":1795370400,"place":{"id":2,"name":"测试地点","address":"测试地址"},"tags":["测试"], ...}
curl -s http://127.0.0.1:8149/feed/ics | head -8
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:adamgibbons/ics
METHOD:PUBLISH
X-PUBLISHED-TTL:PT1H
BEGIN:VEVENT
UID:1@127.0.0.1

至此「发布→API→ICS 订阅」闭环全部打通;测试活动用 curl -X DELETE http://127.0.0.1:8149/api/event/2 -H "Authorization: Bearer <access_token>" 返回 OK 即可清理(实测)。

六、适用场景与限制

6.1 适用场景

  • 社区/协会公开活动页:一个页面聚合展示活动日历,成员自助投稿、编辑审核,替代微信群接龙+网盘图片。
  • Fediverse 活动推广:开启联邦后,活动以 AP 事件对象被 Mastodon 实例订阅/转发(实测 nodeinfo 声明 activitypub),适合去中心化社区。
  • 市政/园区活动聚合:用「集合」把不同场馆/标签拆成子日历,各自出 RSS/ICS feed 供门户嵌入。
  • 只读日历订阅源:把 Gancio 当 ICS 发布器,用户在自己的日历客户端订阅 https://<域名>/feed/ics(实测含 X-PUBLISHED-TTL:PT1H 自动刷新提示)。

6.2 限制(实测/实证)

  • 不是 CalDAV 服务器:无读写日历同步能力,客户端只能订阅静态 ICS,不能把 Gancio 当个人日历后端(与 DAViCal 等的本质差异)。
  • 1.x 停维、2.0 换代中:1.28.2 后 1.x 只修 bug;2.0 截至 2026-10 仍为 beta(2.0.0-beta.8),跨大版本升级路径需观望。
  • 单进程架构:任务管理器与 SSR 渲染同进程,无原生水平扩展/HA;官方定位即小规模社区场景。
  • SQLite 并发上限:SQLITE_BUSY 重试 15 次是官方兜底,投稿量大应切 PostgreSQL。
  • 无内置 TLS:Express 明文监听(实测 curl -I 无 HSTS),需 Nginx/Caddy 反代终结 HTTPS;联邦场景要求 baseurl 为公网可达域名,IP 访问下 webfinger 实测报 Bad request(要求 acct:USER@DOMAIN)。
  • 配置分散:环境变量陷阱(见 3.2)与「settings 改动需重启」是运维期主要困惑来源。

七、同类选型对比

7.1 定位矩阵:发布平台 vs 同步服务器

Gancio 与站内已收官的三款日历方案不是同类竞品,先分清再选:

维度Gancio 1.28.2DAViCal 1.1.13Baïkal 0.10.1Radicale 3.9
物种活动发布平台CalDAV/CardDAV 同步服务器CalDAV/CardDAV 同步服务器CalDAV/CardDAV 同步服务器
技术栈Node.js 20 + Nuxt/ExpressPHP 8 + Apache + PostgreSQLPHP + SQLite/MySQLPython 3
核心协议HTTP+RSS/ICS 只读+ActivityPubCalDAV/CardDAV/iScheduleCalDAV/CardDAVCalDAV/CardDAV
公开网页日历✅(内置 SSR 前端)❌(需第三方前端)弱(极简)❌
Fediverse 联邦✅ 原生❌❌❌
匿名投稿/审核流✅❌❌❌
许可证AGPL-3.0LGPLGPLGPL
中文界面✅(44 语言)部分部分✅

(DAViCal/Baïkal/Radicale 数据取自站内已收官文档,链接见 7.3。)

7.2 与真正的同类(活动发布平台)对比

同物种的自托管选择主要是 Gancio 与 Luma:

维度GancioLuma
技术栈Node.js 单服务Django + PostgreSQL + Redis
联邦ActivityPub 原生ActivityPub(部分)
输出RSS/ICS/JSONRSS/ICS
部署复杂度低(单服务)高(多服务)
社区活跃度月更、2.0 重写中活跃
中文内置 zh弱

Gancio 的差异化优势是单服务极简 + 联邦原生;Luma 更像「线上活动票务页」,无日历订阅生态。

7.3 选型建议(如果…则…)

八、参考链接

Gancio 介绍与选型指南 - Quzuo