Ubuntu 22.04 安装 Dittofeed v0.24.0-alpha.21 指南
在 Ubuntu 22.04 上以源码方式安装 Dittofeed v0.24.0-alpha.21:Node 20 + pnpm 9 + PostgreSQL 15 + ClickHouse 24.12 依赖准备、pnpm 与 yarn 4 两条依赖安装路线的实测卡点、emailo→isomorphic-lib→backend-lib→api/worker/dashboard 构建链、三进程启动日志与健康检查。
Ubuntu 22.04 安装 Dittofeed v0.24.0-alpha.21 指南
目标:在 Ubuntu 22.04 上以源码方式安装 Dittofeed v0.24.0-alpha.21(Node.js 20 + pnpm + PostgreSQL 15 + ClickHouse),完成依赖数据库建库建表、各 Node 服务进程编译与启动、健康检查闭环。文中命令与回显均为本机实跑记录(2026-10-27),源码取自官方仓库 commit
fe89657。组件定位与选型见《Dittofeed v0.24.0-alpha.21 介绍与选型指南》;偏预构建发行版的一键部署路线见预构建发行版部署篇。
源码安装路线的价值在于:可以按需裁剪控制台前端、修改后端逻辑、锁定依赖版本,并且能直接看到每个服务进程的真实启动参数与日志。代价是需要自行解决编译工具链、依赖解析和进程托管,本文把这些卡点逐条记录成可复现的步骤。
一、安装方案与版本矩阵
Dittofeed 是 TypeScript 单体仓库(monorepo),运行期拆成三类 Node 进程:api(Fastify 接口服务)、worker(Temporal 任务执行器)、dashboard(Next.js 控制台),另需三种外部依赖服务:PostgreSQL(业务元数据)、ClickHouse(事件与用户属性存储)、Temporal(Journey 编排)。源码安装即按此依赖顺序逐层落地。
1.1 实测版本矩阵
下表所有版本号均来自本机 --version 回显与源码仓库元数据,不是文档抄录值:
| 组件 | 版本 | 来源与说明 |
|---|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS | /etc/os-release |
| 内核 / CPU | 7.0.0-38-generic / 6 vCPU | uname -r、nproc |
| Node.js | v20.20.2 | NodeSource setup_20.x 安装 |
| npm | 10.8.2 | 随 Node 20 附带 |
| pnpm | 9.15.4 | npm i -g pnpm@9.15.4 |
| PostgreSQL | 15(服务端)/ 14.24(客户端) | 连接串校验;22.04 官方源默认提供 14 客户端 |
| ClickHouse | 24.12.6.70 | clickhouse client --version |
| Temporal | 1.22.4 | 服务端工作流引擎 |
| Dittofeed 源码 | commit fe89657(2026-10-03) | git log -1 |
1.2 进程与端口规划
| 进程 | 默认端口 | 启动入口(编译产物) | 说明 |
|---|---|---|---|
| api | 3001 | packages/api/dist/scripts/startServer.js | API_PORT 可覆盖,本文实测用 3101 |
| worker | 无监听端口 | packages/worker/dist/scripts/startWorker.js | 连 Temporal 轮询任务队列 |
| dashboard | 3000 | next start | 本文实测用 3100 |
💡 技术拓展:Dittofeed 的「事件写入模式」有三个可选值
ch-async(默认,异步批写 ClickHouse)、ch-sync(同步写入,适合测试环境保证读后可见)、kafka(经 Kafka 缓冲,适合高吞吐)。三者写入链路的差异决定了事件「落库延迟」与吞吐上限;本文使用默认ch-async,因此事件上报后到 ClickHouse 可查存在秒级延迟。
二、基础环境与 Node.js 20
2.1 系统基础包
源码构建需要 curl、gnupg、ca-certificates 用于添加软件源与拉取依赖;build-essential 用于少数需要本地编译的依赖。
sudo apt-get update -qq
sudo apt-get install -y curl gnupg ca-certificates build-essential git
2.2 安装 Node.js 20
Dittofeed v0.24.0-alpha.21 的构建脚本与依赖要求 Node 20 及以上(实测 Node 24 亦可运行,但官方仓库以 Node 20 为基准)。使用 NodeSource 源安装:
curl -fsSL https://deb.nodesource.com/setup_20.x -o /tmp/ns.sh
sudo bash /tmp/ns.sh
sudo apt-get install -y nodejs
安装回显(节选):
Preparing to unpack .../nodejs_20.20.2-1nodesource1_amd64.deb ...
Unpacking nodejs (20.20.2-1nodesource1) ...
Setting up nodejs (20.20.2-1nodesource1) ...
版本验证:
node -v && npm -v
v20.20.2
10.8.2
2.3 安装 pnpm 9
sudo npm i -g pnpm@9.15.4
pnpm -v
9.15.4
⚠️ 网络说明:NodeSource 与 npm 官方源在国内访问不稳定。本次安装 npm 全局包时实际发生降级,改用国内 npm 软件源:
npm i -g pnpm@9.15.4 --registry=https://registry.npmmirror.com;后续依赖安装同理(见第四章)。NodeSource 源本次可直连,未降级。
三、依赖数据库:建库与建表
3.1 PostgreSQL 15 建库
Dittofeed 的业务元数据(工作区、用户、Journey、模板、密钥等)存放在 PostgreSQL。服务端要求 15 及以上;本机 PostgreSQL 15 已就绪(psql 连接后由服务端返回版本),客户端使用 Ubuntu 22.04 官方源的 14.24(客户端版本低于服务端不影响使用):
sudo apt-get install -y postgresql-client
psql --version
psql (PostgreSQL) 14.24 (Ubuntu 14.24-0ubuntu0.22.04.1)
创建独立数据库 dittofeed_src,与已有业务库隔离,便于验证安装过程不污染存量数据:
export PGPASSWORD='Dit2feedPg2026'
psql -h 10.89.59.3 -U postgres -d postgres \
-c 'DROP DATABASE IF EXISTS dittofeed_src' \
-c 'CREATE DATABASE dittofeed_src'
DROP DATABASE
CREATE DATABASE
数据库清单确认:
psql -h 10.89.59.3 -U postgres -d postgres -c '\l dittofeed_src'
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------+----------+----------+------------+-----------+-------------------
dittofeed_src | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
(1 row)
⚠️ 3.1 说明:本次实测的三个依赖服务(PostgreSQL 15、ClickHouse 24.12、Temporal 1.22)已在本机网络内就绪,故直接以真实地址
10.89.59.3(PostgreSQL)、10.89.59.2(ClickHouse)、10.89.59.4(Temporal)验证连通;若三者与应用同机安装,把地址换成127.0.0.1即可,端口与账号密码规则不变。数据库内核的安装命令按官方源执行(apt-get install -y postgresql-15或 PGDG 源),本文未重复安装内核,仅做连通、建库、建表与应用行为验证。
3.2 ClickHouse 建表
ClickHouse 存放 user_events_v2 事件主表及派生表。应用默认不会自动建事件表(BOOTSTRAP_EVENTS 默认 false,见第七章实测),因此源码安装建议先用 clickhouse-client 手工建库建表,再启动服务进程。
clickhouse client --version
ClickHouse client version 24.12.6.70 (official build).
连通性校验:
clickhouse client --host 10.89.59.2 --port 9000 \
--user dittofeed --password 'Dit2feedCh2026' \
--query "SELECT version(), currentUser(), currentDatabase()"
24.12.6.70 dittofeed default
建库:
clickhouse client --host 10.89.59.2 --port 9000 \
--user dittofeed --password 'Dit2feedCh2026' \
--query "CREATE DATABASE IF NOT EXISTS dittofeed_src"
建表 DDL 取自源码 packages/backend-lib/src/userEvents/clickhouse.ts 的 createUserEventsTables(),保存为 b1_ch_ddl.sql 后执行:
CREATE TABLE IF NOT EXISTS user_events_v2 (
event_type Enum('identify' = 1, 'track' = 2, 'page' = 3, 'screen' = 4, 'group' = 5, 'alias' = 6)
DEFAULT JSONExtract(message_raw, 'type', 'Enum(''identify'' = 1, ''track'' = 2, ''page'' = 3, ''screen'' = 4, ''group'' = 5, ''alias'' = 6)'),
event String DEFAULT JSONExtract(message_raw, 'event', 'String'),
event_time DateTime64 DEFAULT assumeNotNull(parseDateTime64BestEffortOrNull(JSONExtractString(message_raw, 'timestamp'), 3)),
message_id String,
user_id String DEFAULT JSONExtract(message_raw, 'userId', 'String'),
anonymous_id String DEFAULT JSONExtract(message_raw, 'anonymousId', 'String'),
user_or_anonymous_id String DEFAULT assumeNotNull(coalesce(
JSONExtract(message_raw, 'userId', 'Nullable(String)'),
JSONExtract(message_raw, 'anonymousId', 'Nullable(String)'))),
properties String DEFAULT assumeNotNull(coalesce(
JSONExtract(message_raw, 'traits', 'Nullable(String)'),
JSONExtract(message_raw, 'properties', 'Nullable(String)'))),
hidden Boolean DEFAULT JSONExtractBool(message_raw, 'context', 'hidden'),
processing_time DateTime64(3) DEFAULT now64(3),
server_time DateTime64(3),
message_raw String,
workspace_id String,
INDEX message_id_idx message_id TYPE bloom_filter(0.01) GRANULARITY 4
)
ENGINE = MergeTree()
ORDER BY (workspace_id, processing_time, user_or_anonymous_id, event_time, message_id);
clickhouse client --host 10.89.59.2 --port 9000 \
--user dittofeed --password 'Dit2feedCh2026' \
--database dittofeed_src --multiquery < b1_ch_ddl.sql
建表结果确认:
clickhouse client --host 10.89.59.2 --port 9000 \
--user dittofeed --password 'Dit2feedCh2026' \
--database dittofeed_src --query 'SHOW TABLES'
user_events_v2
空表校验:
clickhouse client --host 10.89.59.2 --port 9000 \
--user dittofeed --password 'Dit2feedCh2026' \
--database dittofeed_src --query 'SELECT count() FROM user_events_v2'
0
注意 ORDER BY 第一列是 workspace_id:多工作区共用一套表,查询计划必须带工作区前缀,否则会全表扫描。这一点在事件量大时直接决定查询耗时。
四、源码获取与依赖安装
4.1 拉取源码
sudo mkdir -p /srv && sudo chown -R "$USER":"$USER" /srv
git clone https://github.com/dittofeed/dittofeed.git /srv/dittofeed
cd /srv/dittofeed
git log -1 --format='%H %ci'
fe89657bbaad3bf25fa3571288287022f12a8347 2026-10-03 18:13:06 -0700
4.2 pnpm 安装依赖:两处实际卡点
仓库根 package.json 声明了 "packageManager": "yarn@4.1.1",pnpm 9 会直接拒绝执行:
cd /srv/dittofeed && pnpm install --no-frozen-lockfile
This project is configured to use yarn because /srv/dittofeed/package.json has a "packageManager" field
Command failed with exit code 1
按仓库现状临时摘除该字段后,pnpm 会把工作区内部包当成外部包去 registry 解析,报找不到 backend-lib:
This error happened while installing a direct dependency of /srv/dittofeed/packages/admin-cli
The latest release of backend-lib is "1.0.4".
补齐工作区链接语义后才能继续:
cd /srv/dittofeed
printf 'link-workspace-packages=true\n' > .npmrc
pnpm install --no-frozen-lockfile --registry=https://registry.npmmirror.com --network-concurrency=32
Progress: resolved 2531, reused 333, downloaded 2031, added 2366, done
依赖确实装下来了(node_modules 约 1.5 GB),但编译阶段失败:pnpm 未在仓库根生成 .bin 链接,tsc 找不到;同时工作区包 emailo 的 dist 未先构建,类型解析报错:
packages/isomorphic-lib build$ NODE_ENV=production tsc --build tsconfig.build.json
packages/isomorphic-lib build: sh: 1: tsc: not found
ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL isomorphic-lib@0.0.3 build
../isomorphic-lib/src/email.ts(5,8): error TS2307: Cannot find module 'emailo' or its corresponding type declarations.
结论:v0.24.0-alpha.21 的依赖声明与锁文件是按 yarn 4 生成的,pnpm 路线在构建阶段无法闭环。生产安装按仓库声明的 yarn 4.1.1 执行:
cd /srv/dittofeed
python3 - <<'EOF'
import json
p = "package.json"
d = json.load(open(p))
d["packageManager"] = "yarn@4.1.1"
open(p, "w").write(json.dumps(d, indent=2) + "\n")
EOF
export YARN_NPM_REGISTRY_SERVER=https://registry.npmmirror.com
node .yarn/releases/yarn-4.1.1.cjs install --mode=skip-build
➤ YN0013: │ 2785 packages were added to the project (+ 369.28 MiB).
➤ YN0000: └ Completed in 27s 884ms
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed in 1m 13s
➤ YN0000: · Done with warnings in 1m 41s
⚠️ 网络说明:依赖安装实测使用国内 npm 软件源
https://registry.npmmirror.com(通过YARN_NPM_REGISTRY_SERVER注入),官方源在本次环境下解析 2500+ 包耗时过长。仓库自带的.yarn/releases/yarn-4.1.1.cjs可直接用node调用,无需全局安装 yarn。
4.3 依赖体积与关键目录
| 路径 | 作用 |
|---|---|
packages/api | Fastify 接口服务,含 /api、/api/admin、/api/public 三组路由 |
packages/worker | Temporal Worker,编译时用 webpack 打包 workflow bundle |
packages/dashboard | Next.js 控制台 |
packages/backend-lib | 数据库 schema、ClickHouse 客户端、bootstrap 逻辑 |
packages/isomorphic-lib | 前后端共享类型与工具 |
packages/emailo | 邮件模板渲染组件库,须最先构建 |
packages/admin-cli | 管理命令行 |
五、编译各服务包
5.1 构建顺序
emailo 被 isomorphic-lib 以类型方式引用,必须先构建,否则后续包全部报 TS2307。构建链按依赖方向逐个执行:
cd /srv/dittofeed
Y='node .yarn/releases/yarn-4.1.1.cjs'
$Y workspace emailo build
$Y workspace isomorphic-lib build
$Y workspace backend-lib build
$Y workspace api build
$Y workspace worker build
emailo 构建回显(节选):
vite v5.4.6 building for production...
✓ 2 modules transformed.
dist/style.css 52.43 kB │ gzip: 8.22 kB
✓ built in 896ms
TypeScript 各包编译成功时无 stdout,用产物确认:
ls packages/api/dist/scripts/startServer.js packages/worker/dist/scripts/startWorker.js
packages/api/dist/scripts/startServer.js
packages/worker/dist/scripts/startWorker.js
5.2 控制台前端构建
cd /srv/dittofeed
node .yarn/releases/yarn-4.1.1.cjs workspace dashboard build
Checking validity of types ...
Creating an optimized production build ...
✓ Compiled successfully
Generating static pages (3/3)
Finalizing page optimization ...
构建产物标识文件 packages/dashboard/.next/BUILD_ID 生成即表示可启动。注意日志中的 TypeScript project references are not fully supported. Attempting to build in incremental mode. 与 zustand/context 弃用提示,均为上游依赖的告警,不影响产物。
六、配置文件
6.1 .env 位置规则
配置加载器 packages/backend-lib/src/config/loader.ts 从「包含 packages 目录的父目录」读取 .env,即进程工作目录在 packages/api 或 packages/worker 下时,实际读取的是 /srv/dittofeed/.env。变量名规则为「配置键名转 CONSTANT_CASE」:databaseHost → DATABASE_HOST、clickhouseHost → CLICKHOUSE_HOST。
本次实测使用的 /srv/dittofeed/.env:
NODE_ENV=production
DATABASE_HOST=10.89.59.3
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASSWORD=Dit2feedPg2026
DATABASE_NAME=dittofeed_src
CLICKHOUSE_HOST=http://10.89.59.2:8123
CLICKHOUSE_USER=dittofeed
CLICKHOUSE_PASSWORD=Dit2feedCh2026
CLICKHOUSE_DATABASE=dittofeed_src
TEMPORAL_ADDRESS=10.89.59.4:7233
SECRET_KEY=Yr9VRRxKWlauoTMLb5Y1E189Mw2eB9KCwdK2qOplzbE=
PASSWORD=q1w2e3r4
BOOTSTRAP=true
AUTH_MODE=single-tenant
WORKSPACE_NAME=Default
DASHBOARD_URL=http://192.168.146.131:8138
DASHBOARD_API_BASE=http://192.168.146.131:8138
LOG_CONFIG=true
6.2 关键项说明
| 变量 | 必填 | 说明 |
|---|---|---|
NODE_ENV | 是 | production 时缺少数据库账号密码会直接抛错 In production must provide database credentials |
DATABASE_HOST/PORT/USER/PASSWORD/NAME | 是 | 也可用单条 DATABASE_URL 合并;DATABASE_URL 优先级更高 |
CLICKHOUSE_HOST | 是 | 支持带协议形式 http://host:8123,缺省端口补 8123 |
CLICKHOUSE_USER/PASSWORD | 是 | 缺省值为 dittofeed / password,生产必须显式设置 |
CLICKHOUSE_DATABASE | 否 | 缺省 dittofeed |
TEMPORAL_ADDRESS | 否 | 缺省 localhost:7233 |
SECRET_KEY | 是 | 会话 Cookie 签名密钥,长度不足或泄露会导致会话异常 |
PASSWORD | 是(单租户) | 单租户模式登录口令,缺省值直接是 password |
AUTH_MODE | 否 | anonymous / single-tenant / multi-tenant,缺省 anonymous |
BOOTSTRAP | 否 | 仅被 lite 入口与 admin-cli 消费,api/worker 进程不执行迁移;源码安装须用 admin-cli bootstrap 初始化 |
BOOTSTRAP_EVENTS | 否 | true 时才自动创建 ClickHouse 事件表 |
LOG_CONFIG | 否 | true 时启动日志打印完整配置(含口令,生产慎开) |
SECRET_KEY 可用如下命令生成,避免使用代码内置默认值:
openssl rand -base64 32
七、启动服务进程与验证
7.1 初始化关系库并启动 api 进程
api 与 worker 进程都不消费 BOOTSTRAP 开关,直接启动后首次查询会报 relation "workspace" does not exist。源码安装必须先单独执行一次 admin-cli 迁移:
cd /srv/dittofeed/packages/admin-cli
NODE_ENV=production node dist/scripts/cli.js bootstrap -n Default
迁移日志(节选):
{"level":30,"msg":"Running migrations"}
{"level":30,"workspaceName":"Default","msg":"Upserting workspace."}
完成后再启动 api 进程:
cd /srv/dittofeed/packages/api
NODE_ENV=production API_PORT=3101 \
nohup node dist/scripts/startServer.js > /var/log/dittofeed-api.log 2>&1 &
实测对照:先以
BOOTSTRAP=true启动 api,随后请求/api/users返回relation "workspace" does not exist;执行上述 admin-cli 命令后表结构才建立(publicschema 共 31 张表,主表为引号大写的"Workspace"、"Secret"、"WriteKey")。仓库自带的scripts/bootstrap.sh调用node ./packages/api/dist/scripts/bootstrap.js,该产物在本版本不存在,属于陈旧脚本,不要使用。
启动日志(配置段节选):
{"level":30,"nodeEnv":"production","databaseUrl":"postgresql://postgres:***@10.89.59.3:5432/dittofeed_src?connect_timeout=60","databaseName":"dittofeed_src","writeMode":"ch-async","temporalAddress":"10.89.59.4:7233","clickhouseHost":"http://10.89.59.2:8123/","clickhouseDatabase":"dittofeed_src","logLevel":"info","bootstrap":true,"bootstrapEvents":false,"bootstrapWorker":true,"authMode":"single-tenant","apiPort":3101,"apiHost":"0.0.0.0","msg":"Initialized with config"}
{"level":30,"msg":"Server listening at http://0.0.0.0:3101"}
BOOTSTRAP_EVENTS 打印为 false,与第 3.2 节「应用不会自动建事件表」的结论一致:ClickHouse 表必须手工建或显式开启该开关。注意日志里 "bootstrap":true 只是回显环境变量取值,api 进程本身并不因此执行迁移(见 7.1)。
7.2 启动 worker 进程
cd /srv/dittofeed/packages/worker
NODE_ENV=production nohup node dist/scripts/startWorker.js > /var/log/dittofeed-worker.log 2>&1 &
关键日志:
{"sdkComponent":"worker","taskQueue":"default","msg":"asset workflow-bundle-76856191bbf0feb6f58f.js 6.33 MiB [emitted] [immutable] (name: main)"}
{"sdkComponent":"worker","taskQueue":"default","size":"6.33MB","msg":"Workflow bundle created"}
{"sdkComponent":"worker","taskQueue":"default","msg":"Worker created"}
{"sdkComponent":"worker","taskQueue":"default","state":"RUNNING","msg":"Worker state changed"}
WARN temporalio_sdk_core::worker::heartbeat: Worker heartbeating configured for runtime, but server version does not support it.
Worker heartbeating configured for runtime, but server version does not support it 是 Temporal 1.22.4 服务端不支持 Worker 心跳的已知告警,不影响任务执行,但意味着控制台里的 Worker 状态判断只能依赖轮询。
7.3 启动控制台
cd /srv/dittofeed/packages/dashboard
NODE_ENV=production nohup node ../../node_modules/next/dist/bin/next start -p 3100 \
> /var/log/dittofeed-dashboard.log 2>&1 &
▲ Next.js 13.5.6
- Local: http://localhost:3100
✓ Ready in 719ms
7.4 健康检查与进程确认
api 进程提供 GET /api 作为健康检查端点(源码 indexController,返回应用版本号):
curl -i -s http://127.0.0.1:3101/api/
HTTP/1.1 200 OK
vary: Origin
access-control-allow-origin: *
content-type: application/json; charset=utf-8
content-length: 2
{}
返回 {} 而非版本号,是因为该端点返回 config().appVersion,而 APP_VERSION 这一环境变量本次未设置;控制台侧同类端点会输出构建哈希(如 {"version":"fe89657"})。健康检查应以 HTTP 200 为准,不要依赖响应体字段做存活判断。
控制台入口:
curl -s -o /dev/null -w 'dashboard code=%{http_code}\n' http://127.0.0.1:3100/dashboard
dashboard code=307
307 是未登录时跳转登录页的正常行为。
进程清单:
ps -eo pid,etime,cmd | grep -E 'startServer|startWorker|next start' | grep -v grep
6539 02:11 node dist/scripts/startServer.js
6642 01:07 node dist/scripts/startWorker.js
7.5 启动顺序小结
- PostgreSQL 15 就绪并建库;
- ClickHouse 就绪并建事件表(或开启
BOOTSTRAP_EVENTS=true); - Temporal 就绪;
- 执行
admin-cli bootstrap -n Default,完成关系库迁移与默认工作区初始化; - api 进程启动;
- worker 进程启动;
- dashboard 启动,登录后验证工作区可用。
7.6 进程托管(systemd 单元)
生产环境应把三个进程交给 systemd 单元管理,示例单元文件(/etc/systemd/system/dittofeed-api.service):
[Unit]
Description=Dittofeed API
After=network-online.target
[Service]
Type=simple
User=dittofeed
WorkingDirectory=/srv/dittofeed/packages/api
EnvironmentFile=/srv/dittofeed/.env
Environment=NODE_ENV=production API_PORT=3001
ExecStart=/usr/bin/node dist/scripts/startServer.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
worker 与 dashboard 用同样结构,改 WorkingDirectory、ExecStart 即可;dashboard 的 ExecStart 为 /usr/bin/node /srv/dittofeed/node_modules/next/dist/bin/next start -p 3000。
⚠️ 实测范围说明:本次实验实例以非系统托管方式(
nohup前台进程)运行,单元文件未在 systemd 下实跑验证;单元文件按上文进程参数编写,启用前请用systemctl daemon-reload && systemctl start dittofeed-api自行确认日志。
八、实测发现的问题清单
| 问题 | 现象(原文) | 影响与处理 |
|---|---|---|
| 仓库声明 yarn,pnpm 被拒 | This project is configured to use yarn because /srv/dittofeed/package.json has a "packageManager" field | pnpm 路线需先摘除 packageManager 字段 |
| pnpm 工作区解析失败 | The latest release of backend-lib is "1.0.4". | 需 .npmrc 设 link-workspace-packages=true |
| pnpm 构建缺 tsc | sh: 1: tsc: not found | 根目录未生成 .bin,改 yarn 4 安装 |
| emailo 未先构建 | error TS2307: Cannot find module 'emailo' | 构建顺序必须 emailo → isomorphic-lib → 其余 |
| 事件表不自动创建 | 启动日志 "bootstrapEvents":false,SHOW TABLES 仅返回手工建的表 | 手工建表或设 BOOTSTRAP_EVENTS=true |
| 健康检查无版本号 | GET /api 返回 {} | APP_VERSION 未设置时无字段,存活判断看 200 |
| 默认口令过弱 | 代码默认 PASSWORD=password、SECRET_KEY 为固定常量 | 必须显式覆盖,否则单租户登录口令即 password |
BOOTSTRAP 不生效 | BOOTSTRAP=true 启动 api 后请求 /api/users 返回 relation "workspace" does not exist | api/worker 不消费该开关,须先跑 admin-cli bootstrap |
| 仓库脚本陈旧 | scripts/bootstrap.sh 调用 node ./packages/api/dist/scripts/bootstrap.js | 该产物在本版本不存在,改用 packages/admin-cli/dist/scripts/cli.js bootstrap |
| Worker 心跳告警 | server version does not support it | Temporal 1.22.4 限制,功能无影响 |
九、收尾检查
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3101/api/ # 期望 200
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3100/dashboard # 期望 307
| 检查项 | 期望 |
|---|---|
| api 端口 | 3101 返回 200 |
| worker 日志 | 出现 Worker state changed 且 state 为 RUNNING |
| dashboard | 返回 307 或 200,无 500 |
| 关系库 | dittofeed_src 中已生成 drizzle 迁移表与默认工作区 |
| 事件库 | user_events_v2 存在,SELECT count() 可执行 |
源码安装完成后的参数调优、REST API 调用与鉴权方式,见本站《Dittofeed v0.24.0-alpha.21 配置参数详解》《Dittofeed v0.24.0-alpha.21 REST API 使用详解》。