Gancio 1.28.2 配置参数详解

Gancio 1.28.2 三层配置模型逐键详解:17 个有效环境变量源码实证与无效变量陷阱、config.json 逐键解读、数据库 settings 表 47 键分组说明、settings 修改的正确姿势,以及切换 PostgreSQL 的完整实测演练。

GancioGancioNodejsSQLitePostgreSQL自托管2026/11/02

Gancio 1.28.2 配置参数详解

目标:Gancio 的「配置」分散在环境变量、config.json、数据库 settings 表三层,是部署后最容易踩坑的架构事实。本文基于 1.28.2 源码逐文件核对(server/config.js、server/initialize.server.js、server/cli.js、server/api/controller/{setup,settings}.js)与运行实例实测(settings 表 47 键全量导出、gancio settings CLI 实测回显、切换 PostgreSQL 完整演练),逐键讲清每层管什么、何时生效、怎么改。部署流程见《Gancio 1.28.2 Docker Compose 部署指南》。

一、环境信息

  • 实测载体:Gancio 1.28.2(Docker Compose 部署,运行时 Node.js v20.19.6),宿主端口 8149 → 服务端口 13120,数据目录 /opt/gancio/data
  • 源码取证:实例程序目录 /home/node/server/(grep -rn "process.env.GANCIO" server/ 全量结果)
  • settings 取证:gancio settings list 全量导出(47 键)+ GET /api/settings(admin 身份)双通道核对
  • PostgreSQL 切换演练:独立 compose 项目(gancio 1.28.2 + postgres:16),全流程实测后已销毁

二、三层配置模型总览

2.1 状态机:谁在什么阶段读哪层

源码实测的启动决策链(config.js 的 load() + initialize.server.js 的 start()):

  1. 进程启动读 -c 指定的配置文件(默认 /home/node/data/config.json):
    • 文件存在 → status=CONFIGURED,配置以文件内容为准;
    • 文件不存在 → status=SETUP,日志打出 > Configuration file does not exists...(实测首启回显)。
  2. CONFIGURED 路径:连库 → 跑增量迁移 → 加载 settings 表 → status=READY,对外提供完整服务。
  3. SETUP 路径:若环境变量 GANCIO_DB_DIALECT 存在,则用 GANCIO_DB_* 组装数据库连接并执行建库迁移(状态转为 DBCONF,此时不写 config.json);否则等待网页向导。
  4. 初始化收尾(网页向导或 POST /api/setup/restart):把本次请求的协议 + Host 头写入 baseurl/hostname,落盘 config.json,创建 admin 随机密码账号,进程自杀,由 restart: always 拉起进入 READY。

💡 实测佐证:PostgreSQL 演练中用 Host: gancio.test 头调用 POST /api/setup/restart,生成的 config.json 即为 "baseurl": "http://gancio.test", "hostname": "gancio.test"——首启时用什么地址访问,站点地址就被写成什么,之后要改只能改 settings(见 5.3)。

2.2 三层分工表

层载体管什么何时生效怎么改
环境变量compose environment数据目录、监听地址、数据库连接(仅首启)、出网代理只在 config.json 生成前参与建库;GANCIO_HOST/PORT 作为 server 段默认值改 compose 后重建服务
运行时配置data/config.json站点地址、监听、日志、数据库连接、上传/文案目录、代理进程启动时读取,改后重启进程生效直接编辑文件
站点设置数据库 settings 表(实测 47 键)标题/简介/语言/时区/功能开关/地图/联邦/主题/SMTP/插件运行时加载,改后需重启服务管理界面 / gancio settings set / POST /api/settings

三、环境变量层

3.1 有效的 17 个变量(源码逐一实证)

grep -rn "process.env.GANCIO" server/ 实测仅命中以下变量(文件与行号来自 1.28.2 源码):

变量读取位置作用与默认值
GANCIO_DATAcli.js:7设置进程工作目录(process.env.cwd),缺省为当前目录。数据目录的根:config.json、gancio.sqlite、logs/、uploads/、user_locale/ 全部相对它解析——这是最要紧的一个变量
GANCIO_HOSTconfig.js:10监听地址,默认 0.0.0.0
GANCIO_PORTconfig.js:11监听端口,默认 13120
GANCIO_DB_DIALECTinitialize.server.js:37首启建库方言:sqlite / postgres / mariadb(fixMariaDBJSON 实证 MariaDB 适配)。SETUP 阶段的开关:不设置则跳过自动建库、纯走向导
GANCIO_DB_STORAGEinitialize.server.js:41SQLite 库文件路径(相对 GANCIO_DATA 解析,实测 ./gancio.sqlite 落为 /home/node/data/gancio.sqlite)
GANCIO_DB_HOST / GANCIO_DB_PORTinitialize.server.js:42-43PG/MariaDB 数据库地址与端口
GANCIO_DB_DATABASE / GANCIO_DB_USERNAME / GANCIO_DB_PASSWORDinitialize.server.js:44-46库名与凭据
GANCIO_PROXY_PROTOCOL / GANCIO_PROXY_HOSTNAME / GANCIO_PROXY_HOST / GANCIO_PROXY_PORTconfig.js:19-22出网代理四件套(联邦/地理编码等外部请求走代理时用),默认空串
GANCIO_PROXY_USERNAME / GANCIO_PROXY_PASSWORDconfig.js:24-25代理认证,写入 proxy.auth
GANCIO_PROXY_HEADERSconfig.js:27代理附加头,必须是合法 JSON(源码直接 JSON.parse),缺省 {}

3.2 无效变量陷阱(高频踩坑)

社区流传的 compose 示例(含部分博客模板)常带以下变量,在 1.28.2 全部源码中零引用,设置不会有任何效果:

无效变量被误认为能干什么实际正确做法
GANCIO_URL / GANCIO_ORIGIN设站点地址settings 键 baseurl/hostname
GANCIO_NAME设站点名称settings 键 title
GANCIO_LOCALE设界面语言settings 键 instance_locale(如 "zh")
GANCIO_TIMEZONE设时区settings 键 instance_timezone(如 Europe/Rome)
GANCIO_EMAIL设管理员邮箱settings 键 admin_email;管理员账号名固定为 admin

⚠️ 本文部署时的实测反例:compose 里设了 GANCIO_LOCALE=zh、GANCIO_TIMEZONE=Europe/Rome,界面语言与时区最终生效靠的是 settings 表中 instance_locale: "zh"、instance_timezone: "Europe/Rome" 两键(gancio settings list 实测),与环境变量无关。源码层证据:initialize.server.js 用 settings.instance_locale/instance_timezone 设置 Luxon 的 Settings.defaultLocale/defaultZone。

四、config.json 层

4.1 实测全量内容与逐键解读

初始化后生成的 /opt/gancio/data/config.json(实测原文,节选合并)与逐键说明:

键实测值说明
baseurlhttp://127.0.0.1:8149站点公开地址。初始化时按当时请求的协议+Host 写入;RSS/ICS 里的链接、联邦对象 ID 都基于它生成,反代上线后必须改(改法见 5.3)
hostname127.0.0.1由 baseurl 派生(config.js load() 实测逻辑:为空时取 baseurl 的 hostname);ICS 的 UID:1@127.0.0.1 即用它
server.host / server.port0.0.0.0 / 13120监听地址与端口,初值来自 GANCIO_HOST/GANCIO_PORT 或默认值
log_leveldebugwinston 日志级别,默认 debug(每个 API 请求都记一行,生产可改 info/warn 降噪)
log_path/home/node/data/logs日志目录(相对 GANCIO_DATA 解析),按天滚动 gancio.YYYY-MM-DD.log,另有 audit.json
db.dialectsqlite数据库方言;改此键即可换库(数据需自行迁移,见第六节)
db.storage/home/node/data/gancio.sqliteSQLite 文件路径;非 sqlite 方言时被置空(实测 PG 演练中为 "")
db.host/port/database/username/password(PG 时出现)外部数据库连接参数,实测见 6.3
db.loggingfalse是否打印 SQL 语句
db.dialectOptions.autoJsonMaptrueSequelize JSON 列自动映射(MariaDB 兼容处理相关,源码 fixMariaDBJSON 实证)
db.retry{ "max": 15 }SQLite 写冲突(SQLITE_BUSY)官方兜底:最多重试 15 次
user_locale/home/node/data/user_locale用户自定义文案目录
upload_path/home/node/data/uploads活动图片上传目录
proxy全空出网代理结构(protocol/hostname/host/port/auth/headers),初值来自 GANCIO_PROXY_*

4.2 修改方式与优先级

  • 直接编辑文件后重启服务:docker compose restart gancio。
  • 优先级实测结论:config.json 存在时(CONFIGURED),数据库连接以文件为准,改 compose 里的 GANCIO_DB_* 不会生效(源码路径:仅 SETUP 分支读 DB 环境变量)。换库要么删/改 config.json 的 db 段,要么全新初始化。
  • CLI 与进程都支持 -c/--config 指定其他配置文件路径(gancio --help 实测默认 /home/node/data/config.json)。

五、settings 层:数据库站点设置 47 键

5.1 查看通道(实测三选一)

docker exec --workdir /home/node/data gancio gancio settings list          # CLI 全量导出
docker exec --workdir /home/node/data gancio gancio settings get title     # 单键
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8149/api/settings  # API(admin)

管理界面(登录后 Admin → Settings)同样读写这张表。实测 CLI 与 API 两通道输出一致,共 47 个键;另有联邦私钥 privateKey 存库但 CLI 列表不回显(初始化日志中打码为 SET privateKey *****)。

5.2 全量键分组详解(实测值即 1.28.2 出厂默认)

站点基本(8 键)

键实测默认值说明
title"Quzuo 社区日历"(向导设定)站点名,RSS channel <title> 同步生效(实测)
description"A shared agenda for local communities"站点简介
baseurl"http://127.0.0.1:8149"站点地址(settings 镜像了一份,与 config.json 联动)
hostname"127.0.0.1"站点主机名
instance_timezone"Europe/Rome"全站时区(Luxon defaultZone,活动展示/ICS 时间换算基准)
instance_locale"zh"界面语言(44 个 locale 之一,zh 实测生效)
instance_name"relay"联邦 Actor 名(/federation/u/relay 实测)
admin_email""管理员收件人(空则不发管理邮件)

活动能力(10 键)

键实测默认说明
allow_registrationtrue允许自助注册(nodeinfo openRegistrations 同步)
allow_anon_eventtrue允许匿名投稿(进待确认队列)
allow_multidate_eventtrue一活动多日期
allow_recurrent_eventfalse重复活动(开启后由 30 分钟一次的 CREATE_RECURRENT_EVENT 任务生成实例)
allow_event_without_end_timetrue允许无结束时间
allow_online_eventtrue线上活动(online_locations 字段)
show_download_mediatrue前端显示图片下载
recurrent_event_visiblefalse重复活动实例是否单独展示
enable_moderationfalse审核模式
enable_reportfalse允许举报

地图与地理编码(5 键,默认关)

键实测默认说明
allow_geolocationfalse地点地理编码 + 地图瓦片总开关
geocoding_provider_type"Nominatim"编码服务商类型
geocoding_provider"https://nominatim.openstreetmap.org/search"编码服务地址(自建可换,官方有 Nominatim 专页)
geocoding_countrycodes[]限定国家码
tilelayer_provider / tilelayer_provider_attributionOSM 瓦片 URL / 版权串地图瓦片源与署名(两键配套)

联邦(5 键)

键实测默认说明
enable_federationtrueActivityPub 联邦总开关
federated_events_in_hometrue首页是否混排联邦来的活动
enable_resourcesfalse资源分享功能
hide_booststrue隐藏转发
default_fedi_hashtags[]发布到联邦时附加话题标签

界面外观(11 键)

键实测默认说明
theme.is_darktrue深色主题(初始化时强制 SET theme.is_dark true,实测日志)
dark_colors / light_colors色板 JSON(primary #FF6E40 / #FF4500 等)深/浅色五色系
hide_thumbs / hide_calendarfalse隐藏缩略图 / 隐藏日历视图
footerLinks[{"/","common.home"},{"/about","common.about"}]页脚链接数组
collection_in_homenull首页默认锁定某集合
calendar_first_day_of_weeknull周起始日
custom_js / custom_css""前端注入脚本/样式(官方有专页)

通知与插件(8 键)

键实测默认说明
smtp{}SMTP 配置对象;管理界面有测试端点(/api/settings/smtp 实证)
plugins[]外部插件列表(data/plugins/)
plugin_Bluesky / plugin_Discord bridge / plugin_Feed / plugin_Telegram / plugin_Webhook均 {"enable":false}5 个内置插件开关(实测启动日志 Do not load ... not enabled)

密钥(1 键)

键说明
publicKey实例 RSA 公钥(联邦签名验签;私钥同库存但 CLI 打码,实测日志 Instance priv/pub key not found, generating....)

5.3 修改 settings 的正确姿势(实测两大坑)

CLI 修改(值必须是合法 JSON):

docker exec --workdir /home/node/data gancio gancio settings set title '"Quzuo 社区日历"'

实测回显:

title
Old value: "Quzuo 社区日历"
New value: "Quzuo 社区日历"

Note that a restart is needed to get the new setting

⚠️ 坑 1(JSON 值):直接传裸字符串会被 JSON.parse 拒绝,实测报错:

SyntaxError: Unexpected token '排', "排错测试" is not valid JSON
    at Object.set [as handler] (/home/node/server/cli/settings.js:42:53)

正确形态是「外层 shell 引号 + 内层 JSON 双引号」:字符串 ' "值" '、布尔 'true'、数组/对象 '["a","b"]'。

⚠️ 坑 2(键名):键名以 settings list 为准,猜键名会撞墙,实测:

gancio settings set locale zh
Setting "locale" does not exists

(语言键是 instance_locale,不是 locale。)

改完必须重启才生效(回显原文 Note that a restart is needed):docker compose restart gancio。

反代上线后改站点地址的标准三连(实测命令形态):

docker exec --workdir /home/node/data gancio gancio settings set baseurl '"https://gancio.example.org"'
docker exec --workdir /home/node/data gancio gancio settings set hostname '"gancio.example.org"'
docker compose restart gancio

六、切换 PostgreSQL 实测演练

小规模社区 SQLite 够用;投稿频繁(SQLITE_BUSY 重试顶到 15 次)或数据量上来时切 PostgreSQL。官方模板即 DB=postgres 一份 compose(sqlite/postgres/mariadb 三选一)。以下为本文独立环境的全流程实测。

6.1 演练 Compose(gancio + postgres:16 双服务)

name: gancio-pgtest

services:
  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=gancio
      - POSTGRES_PASSWORD=gancio
      - POSTGRES_DB=gancio
    volumes:
      - pgdata:/var/lib/postgresql/data

  gancio:
    image: cisti/gancio:1.28.2
    restart: always
    depends_on:
      - db
    environment:
      - GANCIO_DATA=/home/node/data
      - NODE_ENV=production
      - GANCIO_DB_DIALECT=postgres
      - GANCIO_DB_HOST=db
      - GANCIO_DB_PORT=5432
      - GANCIO_DB_DATABASE=gancio
      - GANCIO_DB_USERNAME=gancio
      - GANCIO_DB_PASSWORD=gancio
    volumes:
      - ./data:/home/node/data

volumes:
  pgdata:

6.2 首启自动建库(实测日志)

docker compose up -d

实测 gancio 首启直接连上 PG 并跑完 54 个迁移:

debug: Connecting to DB: {"dialect":"postgres","storage":"","host":"db","port":"5432","database":"gancio","username":"gancio","password":"gancio","logging":false,"dialectOptions":{"autoJsonMap":true}}
debug: == 20191025133803-tags: migrating =======
debug: == 20191025133803-tags: migrated (0.016s)
...
debug: == 20250324211014-to_notify: migrating =======
debug: == 20250324211014-to_notify: migrated (0.003s)

注意 "storage":""——非 sqlite 方言时 storage 被源码强制置空(setup.js _setupDb 实测逻辑)。

6.3 初始化与就绪验证(实测)

演练环境无浏览器,用 POST /api/setup/restart 完成收尾(Host 头即被写入站点地址):

HTTP 200 {"password":"g3jq3j3gqhkv","email":"admin"}

服务被 restart: always 拉起后探活:

HTTP 200 OK

生成的 config.json 数据库段实测:

"db": {
  "dialect": "postgres",
  "storage": "",
  "host": "db",
  "port": "5432",
  "database": "gancio",
  "username": "gancio",
  "password": "gancio",
  "logging": false,
  "dialectOptions": { "autoJsonMap": true }
}

数据库侧确认建表(psql -U gancio -d gancio -c '\dt' 实测节选):

 public | SequelizeMeta | table | gancio
 public | announcements | table | gancio
 public | ap_users      | table | gancio
 public | collections   | table | gancio
 public | event_tags    | table | gancio
 public | events        | table | gancio
 public | filters       | table | gancio
 public | instances     | table | gancio
 public | messages      | table | gancio

演练环境验证后已整体销毁(docker compose down -v)。

6.4 存量实例迁移提醒

  • 环境变量只在「无 config.json」的初始化阶段参与建库:存量实例改 compose 的 GANCIO_DB_* 无效(见 4.2),需改 config.json 的 db 段并重启。
  • 官方文档只提供安装期三选一(sqlite/postgres/mariadb 模板),未提供 SQLite→PostgreSQL 的存量数据转换工具;小数据量可用 API 导出导入(/api/export/json 实测存在)重建,量大则需自行做库间迁移并充分演练。

七、常见配置陷阱速查

症状根因解法
设了 GANCIO_NAME/LOCALE/TIMEZONE 界面无变化源码零引用(3.2)改 settings 对应键并重启
settings set 报 SyntaxError值不是合法 JSON(5.3)字符串加内层双引号
Setting "xxx" does not exists键名猜错先 settings list 查全量键
改完 settings 界面不变未重启docker compose restart gancio
换库后仍连旧库config.json 优先于环境变量改 config.json db 段(4.2)
RSS/ICS/联邦里的链接是 127.0.0.1:8149首启按访问地址写了 baseurl按 5.3 三连改站点地址
日志每请求刷行log_level: debug 出厂默认config.json 改 info 后重启

八、参考链接

站内相关阅读:

Gancio 1.28.2 配置参数详解 - Quzuo