Ghost 中的 Tinybird Connection 文件:格式约束、Secret 注入与 Kafka/S3/GCS 接入实战
在 Ghost 仓库中,Analytics(流量分析)模块基于 Tinybird Forward 构建,所有数据层资源(datasource、pipe、endpoint、connection)均以本地 datafile 作为唯一事实来源,再通过 Tinybird CLI 构建与部署。本文以仓库中 Tinybird Agent 技能规则文件 connection-files.md 为主体,完整讲解 Connection 文件的格式约束、tb_secret 注入语法,以及 Kafka、S3、GCS 三类连接的真实配置示例,并结合 Tinybird Analytics 目录 与 secrets 规则 说明连接在 Ghost 分析链路中的实际落地位置,读完后可直接按仓库规范编写、校验和部署 Connection 文件。
一、Connection 文件在 Ghost 分析链路中的位置
Ghost 的分析数据层位于 ghost/core/core/server/data/tinybird/,目前包含 5 个 datasource 文件、若干 pipe 与 endpoint、fixtures 测试数据以及 YAML 形式的端点测试。按照 SKILL.md 的说明,项目本地文件是事实来源(source of truth),构建目标由 tinybird.config.json 中的 dev_mode(local 或 branch)决定,tb deploy 则面向 Tinybird Cloud 生产环境。
在这个体系中,Connection(.connection)是数据接入层:当数据不通过 HTTP 直接 append,而是从 Kafka topic、S3 或 GCS 桶中周期性/按需导入时,datasource 会通过 IMPORT_CONNECTION_NAME、KAFKA_CONNECTION_NAME 等配置项引用一个 Connection。当前仓库的 datasource(如 analytics_events.datasource)走的是 token 直写 append 模式,仓库中不存在已提交的 .connection 文件——connection-files.md 因此更像是一份面向 Agent 与贡献者的“创建规范”:定义文件长什么样、允许哪些类型、哪些情况必须拒绝。
二、格式约束:五条硬性规则
原文档 connection-files.md 给出的规则是强约束,逐条拆解如下:
- 内容不能为空。Connection 文件至少需要声明
TYPE及对应类型的参数块。空文件在构建时不具备任何语义,会破坏tb build的资源清单。 - Connection 名称必须唯一。名称是 datasource 通过
IMPORT_CONNECTION_NAME等字段引用它时的标识符,重名会导致引用歧义或部署冲突。 - 属性名不允许缩进。这是 Tinybird datafile 的通用格式约定(同样适用于 datasource 文件规则 中的
DESCRIPTION、SCHEMA、ENGINE等属性)。所有顶层属性均顶格书写,多行块内容(如SCHEMA >后的列定义)才有缩进。 - 仅支持三种类型:
kafka、gcs、s3。TYPE行只接受这三种取值。 - 遇到不支持的类型:只报告,不创建。这是给 Agent 的行为边界——当用户要求创建 Redis、Postgres 等仓库规范未覆盖的连接时,正确动作是明确告知该类型不在支持列表中,而不是自行猜测参数格式生成文件,避免产出一个看似合理但无法构建的 datafile。
第 3 条的“无缩进”可以通过仓库中真实的 datasource 文件直观验证,例如 analytics_events.datasource 中 TOKEN、SCHEMA、ENGINE 全部顶格:
TOKEN "tracker" APPEND
TOKEN "analytics-service" APPEND
SCHEMA >
`timestamp` DateTime `json:$.timestamp`,
`session_id` String `json:$.session_id`
...
ENGINE "MergeTree"
ENGINE_PARTITION_KEY "toYYYYMM(timestamp)"
ENGINE_SORTING_KEY "site_uuid, timestamp"
Connection 文件遵循同样的书写风格:TYPE、KAFKA_BOOTSTRAP_SERVERS 等属性名顶格,值紧跟其后。
三、Secret 注入:连接凭证一律走 tb_secret
四个类型示例中,所有敏感值(服务器地址、用户名、密码、Region、ARN、服务账号 JSON)都不是明文,而是通过 Tinybird 模板函数 {{ tb_secret("SECRET_NAME", "DEFAULT_VALUE_OPTIONAL") }} 注入。结合 secrets.md 可以确认几条关键规则:
- Secret 语法固定为
{{ tb_secret("SECRET_NAME", "DEFAULT_VALUE_OPTIONAL") }},用于 connection 与 pipe SQL 中的凭证; - connection 文件中的 secret 允许带默认值(如
"localhost:9092"),pipe 文件中的 secret 不允许默认值——原文档的 Kafka 示例正是利用这一点,本地开发时未设置 secret 就自动落到localhost:9092; - 不得用动态参数(parameters)替代 secret,凭证类占位符必须使用 secret 语法;
- 管理命令:
tb secret ls(可加--match _test过滤)、tb secret set SECRET_NAME SECRET_VALUE、tb secret set SECRET_NAME --multiline(编辑器内输入,适合 JSON 类长文本)、tb secret rm SECRET_NAME; - 本地开发时,若存在
.env.local,Tinybird Local 会自动加载其中的 secret。
最后一条与原文档示例中的默认值设计形成闭环:默认值保证本地可跑,tb secret set 保证生产环境以真实凭证覆盖。
四、三类连接的标准配置示例
以下示例全部继承自 connection-files.md,保持原文可直接复制的形态。
4.1 Kafka 连接
TYPE kafka
KAFKA_BOOTSTRAP_SERVERS {{ tb_secret("PRODUCTION_KAFKA_SERVERS", "localhost:9092") }}
KAFKA_SECURITY_PROTOCOL SASL_SSL
KAFKA_SASL_MECHANISM PLAIN
KAFKA_KEY {{ tb_secret("PRODUCTION_KAFKA_USERNAME", "") }}
KAFKA_SECRET {{ tb_secret("PRODUCTION_KAFKA_PASSWORD", "") }}
要点:KAFKA_SECURITY_PROTOCOL 与 KAFKA_SASL_MECHANISM 是固定协议参数(此处为 SASL_SSL + PLAIN 明文认证),而 bootstrap servers 与 SASL 用户/密码走 secret。secret 名采用 PRODUCTION_* 前缀,语义上明确指向生产环境凭证,默认值(localhost:9092、空串)则服务于本地/测试环境。
4.2 S3 连接
TYPE s3
S3_REGION {{ tb_secret("PRODUCTION_S3_REGION", "") }}
S3_ARN {{ tb_secret("PRODUCTION_S3_ARN", "") }}
仅需 Region 与 ARN 两项。注意与 Kafka 不同,这里没有默认值(均为空串占位),意味着使用 S3 导入时 secret 必须显式配置。
4.3 GCS 连接:两种鉴权方式
GCS 提供 service account 与 HMAC 两种凭证形态,TYPE 相同,参数块不同。
服务账号方式:
TYPE gcs
GCS_SERVICE_ACCOUNT_CREDENTIALS_JSON {{ tb_secret("PRODUCTION_GCS_SERVICE_ACCOUNT_CREDENTIALS_JSON", "") }}
HMAC 方式:
TYPE gcs
GCS_HMAC_ACCESS_ID {{ tb_secret("gcs_hmac_access_id") }}
GCS_HMAC_SECRET {{ tb_secret("gcs_hmac_secret") }}
两种写法的差异值得注意:服务账号示例仍带空串默认值且 secret 名用大写下划线生产前缀,而 HMAC 示例的两个 secret 均不带默认值(secret 名也用小写)。从示例风格看,这体现了“本地可运行的连接才保留默认值”的原则;HMAC 凭证没有可用的本地缺省,因此直接要求 secret 存在。
五、下游消费:Connection 如何被 datasource 引用
Connection 本身不处理数据,它的价值体现在 datasource 的导入配置上。datasource-files.md 规定了三种连接类型对应的标准导入参数:
- S3/GCS:设置
IMPORT_CONNECTION_NAME、IMPORT_BUCKET_URI、IMPORT_SCHEDULE;其中 GCS 仅支持@on-demand调度,S3 支持@auto(自动调度导入); - Kafka:设置
KAFKA_CONNECTION_NAME、KAFKA_TOPIC、KAFKA_GROUP_ID。
也就是说,第四节的 .connection 文件提供“怎么连”(类型、鉴权),datasource 提供“连什么、何时导”(桶 URI、topic、调度频率),两者以 connection name 关联——这正是第二节“名称必须唯一”规则的实际意义。
以 Ghost 仓库现有的 analytics_events.datasource 为例,它并未引用 connection,而是通过两行 TOKEN ... APPEND 让 tracker 与分析服务直接追加数据,schema 使用 json:$.xxx 路径解析 NDJSON 载荷,引擎为 MergeTree、按月分区(toYYYYMM(timestamp))、按 site_uuid, timestamp 排序。该文件同时展示了规则中提到的 FORWARD_QUERY 用法(schema 不兼容变更时的读时转换)。可以推断:一旦 Ghost 需要把分析事件改为从消息队列或对象存储导入,新增的 .connection 文件将按本文第二节至第四节的格式创建,datasource 则按第五节参数引用它,其余管道结构不变。
六、本地开发、构建与验证
围绕 Connection 文件的日常操作,仓库提供了两条并行的本地路径(详见 Tinybird README):
- Docker 方式(推荐):从仓库根目录执行
docker compose --profile analytics up -d启动本地 Tinybird 容器并部署 datafiles,再执行docker compose --profile split up启动 Ghost 服务;不安装 CLI 也可通过docker compose run --rm -it tb-cli tb <command>在容器内执行任意tb命令,tb dev会以 watch 模式持续自动部署文件变更; - 本地 CLI 方式:首次执行
pnpm tb:install安装 Tinybird CLI,之后用pnpm tb启动本地 Tinybird。
与 Connection 直接相关的验证动作:
tb secret ls/tb secret set <NAME> <VALUE>准备各 secret(Kafka、S3、GCS 示例中出现的PRODUCTION_*名称);- 修改
.connection或 datasource 文件后由tb dev自动重新部署,或在生产链路中使用tb build(按dev_mode指向本地或分支)与tb deploy(指向 Cloud 生产); - 端点级验证可参考 tests/ 目录 中按 pipe 命名的 YAML 测试,fixtures(如 analytics_events.ndjson)提供本地追加数据;注意 fixtures 重建数据时物化视图只做追加、不清理旧数据,README 建议追加前先 truncate 全部数据源以保证一致性。
本地 Tinybird 的容器化实现分别位于 docker/tinybird-local-slim/Dockerfile 与 docker/tb-cli/Dockerfile,供 compose 环境复用。
小结
- Connection 文件遵循“非空、名称唯一、属性顶格不缩进”的格式约束,
TYPE仅支持kafka、gcs、s3,遇到其他类型只报告不创建; - 凭证统一通过
{{ tb_secret("NAME", "DEFAULT") }}注入,connection 文件允许默认值(利于本地开发),pipe 文件不允许; - Kafka 连接配 bootstrap servers + SASL 参数,S3 配 Region + ARN,GCS 按场景选择服务账号 JSON 或 HMAC 凭证;
- Connection 由 datasource 的
IMPORT_*/KAFKA_*导入参数消费,GCS 仅支持@on-demand、S3 支持@auto调度; - 本地链路以 Tinybird Local(Docker 或 CLI)承载,
tb devwatch 部署、tb secret管理凭证、YAML 测试与 ndjson fixtures 完成闭环验证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00