Lowdefy 配置参数详解

以可运行工单看板为例,逐项拆解 lowdefy.yaml 的应用级参数、pages/blocks、connections/requests、auth 与 global/menus,附 build/dev/start 与请求 API 实测回显。

LowdefyLowdefy低代码Node.jsMongoDB2026/10/28

Lowdefy 配置参数详解

目标:以一份可运行的低代码工单看板为样本,逐项拆解 lowdefy.yaml 的应用级参数、pages/blocks、connections/requests、auth 与 global/menus,并给出每项参数修改后的实测结果。文中配置与回显均来自 Ubuntu 22.04.5 + Lowdefy 7.1.0 实测(2026-10-27)。

一、环境信息

项目取值
操作系统Ubuntu 22.04.5 LTS(x86_64)
Node.jsv24.22.1
Lowdefy CLI7.1.0
MongoDB7.0.45
实验应用目录/opt/lowdefy/c1
生产服务端口3005/tcp
开发服务端口3006/tcp(页面预览实际监听 3007/tcp)
认证方式Better Auth + 邮箱密码
实测日期2026-10-27

应用名称在日志中显示为 Lowdefy C1 Lab,版本 0.1.0。本文所有“实测回显”均取自该应用的 build、dev、start 日志与 HTTP 请求结果。

二、前置条件

阅读并复现本文前,确认以下条件已满足:

  • 已按 《Ubuntu 22.04 安装 Lowdefy 指南》 完成 Node.js 24、pnpm 与 Lowdefy CLI 安装。
  • 已初始化应用目录,根目录存在 lowdefy.yaml。
  • MongoDB 已运行,本文使用 mongodb://127.0.0.1:27017,业务库为 lowdefy_c1。
  • 已准备两个运行时密钥,通过环境变量注入,不写进配置文件:
    • LOWDEFY_SECRET_MONGODB_URI:MongoDB 连接串。
    • LOWDEFY_SECRET_AUTH_SECRET:认证签名密钥,长度不少于 32 个字符。
  • 3005、3006、3007 端口未被占用。

启动生产服务前的环境变量注入方式如下,后续章节直接复用:

export LOWDEFY_SECRET_MONGODB_URI="mongodb://127.0.0.1:27017"
export LOWDEFY_SECRET_AUTH_SECRET="c1-auth-secret-0123456789"

三、参数查看与修改方式

3.1 配置文件与加载顺序

Lowdefy 只要求根目录存在一个 lowdefy.yaml,其余配置都从它出发按 _ref 引用加载:

  • lowdefy.yaml:应用入口,声明版本、应用级参数、connections、auth,以及 pages 数组。
  • pages/*.yaml:页面文件,通过 - _ref: pages/home.yaml 挂载,避免单文件膨胀。
  • 被引用的文件可以是 YAML,也可以是 JSON;根文件本身必须是 YAML。
  • _secret 运算符在构建和运行时求值,用于从 LOWDEFY_SECRET_<名称> 环境变量读取敏感值。

本文实验应用的根配置如下(节选,完整版见第六章):

lowdefy: 7.1.0
name: Lowdefy C1 Lab
version: 0.1.0
slug: lowdefy-c1
description: Lowdefy 配置参数实测
license: Apache-2.0

cli:
  port: 3000
  disableTelemetry: true

config:
  homePageId: home

global:
  appTitle: 低代码工单看板

pages:
  - _ref: pages/home.yaml
  - _ref: pages/admin.yaml

pages 下的两个条目不是内联页面,而是引用外部文件;构建时会把引用展开成完整页面树。这一结构在本文实验中构建成功,两个页面均可访问。

3.2 用 build 校验参数

改完配置后,先用 build 做一次全量校验。它会检查 YAML 语法、引用是否存在、必填参数是否齐全,以及认证等模块的配置约束:

cd /opt/lowdefy/c1
lowdefy build

实测回显(已去除终端颜色控制符):

17:05:56 ∙ Running 'lowdefy build'. Lowdefy app version 7.1.0.
17:05:56 ∙ Starting build.
17:05:56 ∙ Dependencies unchanged.
- Running Lowdefy build.
17:05:56 ∙ $ node lowdefy/build.mjs
17:05:57 ∙ /bin/sh: 1: git: not found
17:05:57 ∙ Lowdefy build successful.
- Installing dependencies.
17:05:58 ∙ Dependencies install successfully.
- Running client build.
17:05:59 ∙ Client bundle size (gzip): 329.72 kB.
17:05:59 ∙ Client build successful.
17:05:59 ✔ Build successful.

回显中的 git: not found 是构建过程调用 git 获取版本信息时的提示,不影响构建结果,最终仍输出 Build successful。若参数有误,构建会直接失败并给出带文件行号的错误,例如第五章 5.5 节的认证配置错误。

3.3 dev 模式查看改动结果

开发模式会监听配置文件变化并自动重建配置,适合逐项调参:

cd /opt/lowdefy/c1
lowdefy dev --port 3006 --no-open

实测回显(已去除终端颜色控制符):

17:06:27 ∙ Running 'lowdefy dev'. Lowdefy app version 7.1.0.
17:06:27 ∙ Starting development server.
- Fetching @lowdefy/server-dev from npm.
17:06:29 ∙ Fetched @lowdefy/server-dev from npm.
- Installing dependencies.
17:06:30 ∙ Dependencies install successfully.
- Building config...
17:06:30 ∙ /bin/sh: 1: git: not found
17:06:31 ✔ Built config in 629ms.
17:06:31 ⚠ Mock user active - login bypassed
17:06:32 ∙   VITE v8.0.16  ready in 180 ms
17:06:32 ∙   ➜  Local:   http://127.0.0.1:3007/

注意两点:--port 3006 是 CLI 服务端口,页面预览由 Vite 在 3007 提供;Mock user active - login bypassed 表示配置中的 auth.dev.mockUser 已生效,开发模式下跳过登录。

3.4 用请求 API 验证配置

配置是否真正生效,最终要看服务端行为。Lowdefy 为每个页面请求暴露固定路径:

POST /api/request/{pageId}/{requestId}

请求体必须是合法 JSON,且业务数据要放在 payload 键下。下面以读取工单为例,服务运行在 3005:

curl -s -X POST -H "Content-Type: application/json" \
  -d '{}' \
  http://localhost:3005/api/request/home/get_tickets

实测回显:

{"id":"request:home:get_tickets","success":true,"type":"MongoDBFind","response":[{"_id":{"_oid":"6ae0dd011367051a24439f78"},"title":"网络故障","status":"open","created_at":{"~d":1793121537195}},{"_id":{"_oid":"6ae0dc441367051a24439f77"},"title":null,"status":"open","created_at":{"~d":1793121348888}}]}

返回结构固定包含 id、success、type、response 四个字段。MongoDB 的 ObjectId 序列化为 {"_oid":"..."},Date 序列化为 {"~d":毫秒时间戳},调用方需要按此结构解析。

四、参数总览

lowdefy.yaml 的顶层键及其作用如下:

参数是否必需作用本文是否实测
lowdefy必需声明应用使用的 Lowdefy 版本是
name可选应用名称,出现在服务端日志是
version可选应用版本,日志中显示为 app_version是
slug可选应用标识是(构建通过)
description可选应用描述是(构建通过)
license可选许可证标识是(构建通过)
cli可选CLI 行为,如默认端口、遥测开关是
config可选运行配置,如首页 id、超时、安全策略是
global可选全局变量,供 _global 运算符读取是
menus可选导航菜单定义是(构建通过)
auth条件必需启用登录、角色与页面保护时必须配置是
connections条件必需使用数据库或外部 API 时必须配置是
pages必需页面定义,可用 _ref 拆分是

auth 的“条件必需”含义是:只要声明了除 auth.dev 之外的认证键,就必须同时提供登录机制、secret 和 database,否则构建失败。

五、核心参数分类详解

5.1 应用级参数

应用级参数决定“这是什么应用、默认怎么跑”。本文实验值如下:

lowdefy: 7.1.0
name: Lowdefy C1 Lab
version: 0.1.0

cli:
  port: 3000
  disableTelemetry: true

config:
  homePageId: home

各参数含义与实测结论:

  • lowdefy:配置语法与运行时版本。CLI 会读取该值判断是否需要升级,本文构建日志中的版本提示即来自此处与 CLI 版本的比对。
  • name / version:只影响日志与展示,不改变路由。启动日志中显示为 app_name: Lowdefy C1 Lab、app_version: 0.1.0。
  • cli.port:默认端口。本文设为 3000,但启动时用 --port 3005 覆盖,服务最终监听 3005,说明命令行参数的优先级高于 cli.port。
  • cli.disableTelemetry:关闭遥测上报,适合内网部署。
  • config.homePageId:访问根路径 / 时加载的页面 id。本文设为 home,匿名访问 / 返回 200,服务端日志记录 pageId: home。

验证首页参数:

curl -s -o /dev/null -w "status=%{http_code}\n" http://localhost:3005/

实测回显:

status=200

服务端对应日志:

17:06:18 ∙   event: page_view
17:06:18 ∙   pageId: home
17:06:18 ∙   path: home

5.2 pages 与 blocks

pages 是应用的主体,每一项至少要有 id 与 type。type 决定页面外壳,本文使用 PageHeaderMenu,自带页头与菜单区域。

页面级字段如下:

字段作用
id页面唯一标识,也是路由与权限判断的依据
type页面块类型,如 PageHeaderMenu
properties页面属性,如标题
requests页面内可调用的请求定义
events页面生命周期事件,如 onMount
blocks页面内容块数组

首页配置(节选):

id: home
type: PageHeaderMenu
properties:
  title: 工单看板
requests:
  - id: get_tickets
    type: MongoDBFind
    connectionId: tickets_connection
    properties:
      query: {}
events:
  onMount:
    - id: load_tickets
      type: Request
      params: get_tickets
blocks:
  - id: page_title
    type: Title
    properties:
      content:
        _global: appTitle

blocks 中每个块同样以 id 与 type 为必需字段,可嵌套 blocks 形成布局树:

- id: list_card
  type: Card
  properties:
    title: 工单列表
  blocks:
    - id: tickets_table
      type: TableLight
      properties:
        rowKey: _id
        columns:
          - key: title
            title: 标题
          - key: status
            title: 状态
        data:
          _request: get_tickets

实测结论:把页面拆到 pages/home.yaml 与 pages/admin.yaml 再由根配置 _ref 挂载后,构建成功;TableLight 通过 _request: get_tickets 绑定请求结果,返回的数组可直接作为表格数据源。块 id 只要求在同一页面内唯一,跨页面可复用。

5.3 connections

connections 定义与外部服务的连接,位于配置根部。每个连接必须有 id、type、properties。本文使用 MongoDB 集合连接:

connections:
  - id: tickets_connection
    type: MongoDBCollection
    properties:
      databaseUri:
        _secret: MONGODB_URI
      databaseName: lowdefy_c1
      collection: tickets
      write: true

参数说明:

  • databaseUri:连接串,用 _secret: MONGODB_URI 读取 LOWDEFY_SECRET_MONGODB_URI,避免明文入库。
  • databaseName / collection:定位到具体库与集合,本文为 lowdefy_c1.tickets。
  • write: true:允许该连接执行写入类请求。本文的写入请求执行成功,说明该参数已放开写操作。

连接属性中的运算符在每次请求调用时重新求值,因此可以在 properties 中引用会变化的上下文,而不必为每次调用重建连接。

5.4 requests

requests 是连接的具体用法,必须声明 id、type、connectionId,并按请求类型提供 properties。本文定义一读一写两个请求:

requests:
  - id: get_tickets
    type: MongoDBFind
    connectionId: tickets_connection
    properties:
      query: {}
      options:
        sort:
          - - created_at
            - -1
  - id: insert_ticket
    type: MongoDBInsertOne
    connectionId: tickets_connection
    payload:
      ticket_title:
        _state: ticket_title
    properties:
      doc:
        title:
          _payload: ticket_title
        status: open
        created_at:
          _date: now

关键字段与求值位置:

字段求值位置说明
payload客户端可用 _state 读取输入框等客户端状态
properties服务端用 _payload 读取上一步 payload 的值
connectionId构建时校验必须指向已定义的连接 id
type构建时校验必须是连接支持的类型

写入请求的实测调用需要把业务值放进 payload 键:

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"payload":{"ticket_title":"网络故障"}}' \
  http://localhost:3005/api/request/home/insert_ticket

实测回显:

{"id":"request:home:insert_ticket","success":true,"type":"MongoDBInsertOne","response":{"acknowledged":true,"insertedId":{"_oid":"6ae0dd011367051a24439f78"}}}

再次读取可看到标题已正确写入:

{"id":"request:home:get_tickets","success":true,"type":"MongoDBFind","response":[{"_id":{"_oid":"6ae0dd011367051a24439f78"},"title":"网络故障","status":"open","created_at":{"~d":1793121537195}},{"_id":{"_oid":"6ae0dc441367051a24439f77"},"title":null,"status":"open","created_at":{"~d":1793121348888}}]}

这里有一个容易踩坑的实测细节:payload 在客户端求值,直接调用 HTTP API 时并没有浏览器状态,若不按 {"payload":{...}} 传值,_state: ticket_title 会解析为空,写入的 title 就是 null。要让接口调用拿到值,必须显式提供 payload。

请求体不合法时服务端返回 400,而不是 500:

curl -s -o /dev/null -w "status=%{http_code}\n" -X POST http://localhost:3005/api/request/home/get_tickets

实测回显:

status=400

响应体:

{"name":"UserError","message":"Request body is not valid JSON."}

用 GET 访问同一路径则返回 405:

{"error":"Method not allowed."}

5.5 auth

auth 是参数最多、约束最严的一块。本文目标有三项:启用邮箱密码登录、声明 admin/viewer 两个角色、只允许 admin 访问管理页。

先看约束。只写 roles 与 pages.roles 而不给登录机制时,构建直接失败:

17:05:32 ∙ /opt/lowdefy/c1/lowdefy.yaml:32
17:05:32 ✖ [ConfigError] Auth is configured without an authentication mechanism. Configure a login method ("emailAndPassword.enabled: true", "magicLink.enabled: true", "emailOTP.enabled: true" or "phoneNumber.enabled: true"), or an OAuth provider in "providers", or an API auth strategy in "strategies".
17:05:32 ∙ Build failed with 1 error(s). See above for details.

补齐登录机制、secret 与 database 后构建通过:

auth:
  secret:
    _secret: AUTH_SECRET
  database:
    id: auth_db
    type: MongoDBAuthAdapter
    properties:
      uri:
        _secret: MONGODB_URI
  emailAndPassword:
    enabled: true
  roles:
    - id: admin
    - id: viewer
  pages:
    roles:
      admin:
        - admin_page
  dev:
    mockUser:
      id: admin
      email: admin@example.com
      name: 管理员
      roles:
        - admin

各参数作用:

  • secret:Better Auth 的签名密钥,建议至少 32 个字符。本文用短密钥启动,服务端给出两条警告:
17:06:10 ⚠ Auth "secret" is shorter than 32 characters. Use a long random value, e.g. `openssl rand -base64 32`.
17:06:10 ⚠ [better-auth] Warning: your BETTER_AUTH_SECRET should be at least 32 characters long for adequate security. Generate one with `npx auth secret` or `openssl rand -base64 32`.
  • database:认证数据存储,MongoDBAuthAdapter 把用户、会话写入 MongoDB;properties.uri 同样走 _secret。
  • emailAndPassword.enabled:启用邮箱密码登录。未配置 auth.email 时无法发送重置邮件,启动日志会提示:
17:06:10 ⚠ Auth "email" is not configured - password reset emails cannot be sent, so the reset flow is unavailable.
  • roles:声明应用使用的角色名,供页面与接口授权引用。
  • pages.roles:角色到页面 id 数组的映射,本文把 admin_page 绑定到 admin。
  • dev.mockUser:仅开发模式使用的模拟用户,注入后跳过登录流程。

页面保护的实测对比:

# 公开页:匿名可访问
curl -s -o /dev/null -w "home status=%{http_code}\n" http://localhost:3005/
# 受保护页:匿名被重定向到登录页
curl -s -o /dev/null -w "admin status=%{http_code} redirect=%{redirect_url}\n" http://localhost:3005/admin_page

实测回显:

home status=200
admin status=302 redirect=http://localhost:3005/login?callbackUrl=%2Fadmin_page

同一受保护页在开发模式下由 dev.mockUser(角色 admin)访问,返回 200:

dev admin status=200

对应开发日志:

17:06:31 ⚠ Mock user active - login bypassed

需要强调:dev.mockUser 是绕过认证引擎的模拟身份,只用于开发调试;生产环境的页面拦截以上面的 302 重定向为准。这也是为什么生产验证要单独用匿名请求做一次。

5.6 global 与 menus

global 存放跨页面共享的变量,通过 _global 运算符读取:

global:
  appTitle: 低代码工单看板

页面标题块直接引用:

- id: page_title
  type: Title
  properties:
    content:
      _global: appTitle

修改 global.appTitle 后,所有引用 _global: appTitle 的块会同步变化,不需要逐页改动。

menus 定义导航结构,每项包含菜单 id 与 links 数组,链接用 MenuLink 指向页面 id:

menus:
  - id: main_menu
    links:
      - id: home_link
        type: MenuLink
        pageId: home
        properties:
          title: 首页
      - id: admin_link
        type: MenuLink
        pageId: admin_page
        properties:
          title: 管理页

pageId 必须是已定义的页面 id,否则构建阶段会报引用错误。本文两个链接均指向实际页面,构建通过。

六、生产配置模板

以下模板把本文验证过的参数组合成一份可直接改用的生产配置。密钥全部走环境变量,不落盘。

根配置 lowdefy.yaml:

lowdefy: 7.1.0
name: Lowdefy C1 Lab
version: 0.1.0
slug: lowdefy-c1
description: Lowdefy 配置参数实测
license: Apache-2.0

cli:
  port: 3000
  disableTelemetry: true

config:
  homePageId: home

global:
  appTitle: 低代码工单看板

menus:
  - id: main_menu
    links:
      - id: home_link
        type: MenuLink
        pageId: home
        properties:
          title: 首页
      - id: admin_link
        type: MenuLink
        pageId: admin_page
        properties:
          title: 管理页

auth:
  secret:
    _secret: AUTH_SECRET
  database:
    id: auth_db
    type: MongoDBAuthAdapter
    properties:
      uri:
        _secret: MONGODB_URI
  emailAndPassword:
    enabled: true
  roles:
    - id: admin
    - id: viewer
  pages:
    roles:
      admin:
        - admin_page

connections:
  - id: tickets_connection
    type: MongoDBCollection
    properties:
      databaseUri:
        _secret: MONGODB_URI
      databaseName: lowdefy_c1
      collection: tickets
      write: true

pages:
  - _ref: pages/home.yaml
  - _ref: pages/admin.yaml

页面文件 pages/home.yaml(节选):

id: home
type: PageHeaderMenu
properties:
  title: 工单看板
requests:
  - id: get_tickets
    type: MongoDBFind
    connectionId: tickets_connection
    properties:
      query: {}
      options:
        sort:
          - - created_at
            - -1
  - id: insert_ticket
    type: MongoDBInsertOne
    connectionId: tickets_connection
    payload:
      ticket_title:
        _state: ticket_title
    properties:
      doc:
        title:
          _payload: ticket_title
        status: open
        created_at:
          _date: now
events:
  onMount:
    - id: load_tickets
      type: Request
      params: get_tickets

运行时密钥清单:

环境变量用途要求
LOWDEFY_SECRET_MONGODB_URI业务库与认证库连接串可被 MongoDB 客户端直接使用
LOWDEFY_SECRET_AUTH_SECRET认证签名密钥至少 32 个字符的随机值

启动与实测回显:

cd /opt/lowdefy/c1
lowdefy start --port 3005
17:06:09 ∙ Running 'lowdefy start'. Lowdefy app version 7.1.0.
17:06:09 ✔ Started server.
17:06:10 ∙ Lowdefy server listening on http://localhost:3005
17:06:10 ∙   app_name: Lowdefy C1 Lab
17:06:10 ∙   app_version: 0.1.0
17:06:10 ∙   server: lowdefy
17:06:10 ∙   port: 3005
17:06:10 ∙   lowdefy_version: 7.1.0

服务启动后即可用第三章的请求 API 逐项验证。生产部署建议把上述环境变量写入 EnvironmentFile,由 systemd 托管,具体步骤见 《Ubuntu 22.04 安装 Lowdefy 指南》。

七、常见问题

7.1 构建报 Auth is configured without an authentication mechanism

现象:只配置 auth.roles、auth.pages.roles 时构建失败,退出码 1。

✖ [ConfigError] Auth is configured without an authentication mechanism. Configure a login method ("emailAndPassword.enabled: true", "magicLink.enabled: true", "emailOTP.enabled: true" or "phoneNumber.enabled: true"), or an OAuth provider in "providers", or an API auth strategy in "strategies".

原因:auth 一旦声明为真实认证栈,就必须有登录机制、secret 和 database。

处理:补齐三件套。本文补上 auth.secret、MongoDBAuthAdapter 与 emailAndPassword.enabled: true 后构建成功。

7.2 认证密钥过短的警告

现象:服务能启动,但日志连续输出警告,提示 secret 短于 32 个字符、熵不足。

原因:Better Auth 对签名密钥长度有安全要求,短密钥不会被拒绝启动,但会削弱会话安全。

处理:用 openssl rand -base64 32 生成随机值,写入 LOWDEFY_SECRET_AUTH_SECRET 后重启。本文为复现警告特意使用了短值,生产环境不要沿用。

7.3 Request body is not valid JSON

现象:POST 请求返回 400。

{"name":"UserError","message":"Request body is not valid JSON."}

原因:没有发送请求体,或请求体不是合法 JSON。

处理:始终带 Content-Type: application/json,并至少发送 {}。需要向请求传值时,按 {"payload":{"字段名":"值"}} 的格式发送。

7.4 受保护页面返回 302

现象:访问 /admin_page 得到 302,跳转到 /login?callbackUrl=%2Fadmin_page。

原因:该页面已通过 auth.pages.roles 绑定到 admin 角色,而当前请求没有登录会话。

处理:这是预期的保护行为。开发阶段可用 auth.dev.mockUser 或 lowdefy dev --mock-user 注入模拟身份,生产环境应完成真实登录后再访问。

7.5 修改配置后页面没有变化

现象:改了 lowdefy.yaml,运行中的生产服务没有反映新配置。

原因:lowdefy start 读取的是 .lowdefy/server 下的构建产物,不是源配置。

处理:先停止服务,重新执行 lowdefy build,再执行 lowdefy start。开发模式 lowdefy dev 会自动重建,不需要手动 build。

7.6 配置端口与实际监听端口不一致

现象:cli.port 写的是 3000,服务却监听 3005。

原因:启动命令带了 --port 3005,命令行参数优先。

处理:二者取其一即可。需要固定端口时,删掉命令行的 --port,只保留 cli.port;需要临时换端口时,用命令行覆盖。

八、参考链接

站内文档:

官方资料:

  • Lowdefy 官方文档:https://docs.lowdefy.com
  • 应用配置 Schema:https://docs.lowdefy.com/lowdefy-schema
  • 连接与请求:https://docs.lowdefy.com/connections-and-requests
  • 认证配置:https://docs.lowdefy.com/auth-configuration
  • 角色与页面权限:https://docs.lowdefy.com/roles
  • 部署到 Node.js:https://docs.lowdefy.com/node-server