bewCloud v4.21.0 配置参数详解

讲透 bewCloud v4.21.0 双层配置体系:.env 密钥环境变量与 bewcloud.config.ts 七域 30 项参数的加载合并机制、逐项默认值与取值影响、两套分场景生产配置模板与配置不生效排障,默认值取自官方 DEFAULT_CONFIG 源码并在实测环境验证。

bewCloudbewCloud文件共享自托管2026/10/30

bewCloud v4.21.0 配置参数详解

目标:讲透 bewCloud v4.21.0 的双层配置体系——.env 密钥环境变量与 bewcloud.config.ts 业务配置七个域共 30 个参数:加载与合并机制、逐项默认值与取值影响、两套分场景生产配置模板,以及改配置不生效、配置回退等典型问题的定位方法。默认值全部取自官方 lib/config.ts 的 DEFAULT_CONFIG 源码(2026-10-30 实查),行为结论在实测环境验证。

本文是 bewCloud 系列的第三篇。部署过程见 《bewCloud v4.21.0 Docker Compose 部署指南》,参数如何影响 API 行为的调用实测见 《bewCloud v4.21.0 API 使用详解》。

一、环境信息

项目值
组件版本bewCloud v4.21.0
配置源码官方仓库 lib/config.ts(DEFAULT_CONFIG)与 bewcloud.config.sample.ts,2026-10-30 实查
配置载体.env(密钥类环境变量,12 项)+ bewcloud.config.ts(业务配置,7 域 30 项)
实测环境Linux x86_64,Docker Compose 三服务部署(应用 8000 → 宿主 8155),2026-10-30 实测
实测账号admin@example.com / q1w2e3r4(首用户管理员)

bewCloud 的配置面在 v2 重写时定型为两层:描述行为的进 bewcloud.config.ts(TypeScript 文件,类型安全、可版本管理),会泄露身份的进 .env(环境变量,不进版本库)。本篇把两层放在一起逐项讲清。

二、前置条件

  1. 已按部署篇完成三服务部署并能登录(本篇的验证命令基于运行中的实例);
  2. 能编辑部署目录下的两个文件:.env 与 bewcloud.config.ts;
  3. 理解一个前提:bewCloud 没有运行时管理后台,注册开关、上传限额这类"管理动作"全部通过改配置文件完成——改完按第三节的方式重载生效。

三、参数查看与修改方式

3.1 配置的加载与合并机制

应用启动时按固定顺序加载配置(来源:lib/config.ts loadConfig 实现,2026-10-30 实查):

  1. 取内置 DEFAULT_CONFIG 作为基底(即第四节总览表中的「默认值」列);
  2. 从工作目录 import bewcloud.config.ts 的 default 导出,按域(auth/files/core/visuals/email/contacts/calendar)逐域深合并——你只写改动的键,其余键自动落到默认值;
  3. 加载成功时向标准输出打印一行 Config loaded from bewcloud.config.ts 与合并后的全量配置 JSON——这是运行时核对配置是否生效的第一手段;
  4. 文件缺失或语法错误时打印 Error loading config from bewcloud.config.ts. Using default config instead. 并静默回退默认配置继续运行——服务不会因配置错误起不来,但行为会回到默认,这是「改了不生效」问题的第一大来源。

实测:查看当前实例合并后的生效配置(输出节选,实测首尾):

docker compose logs website 2>&1 | grep -A 60 'Config loaded'

实测回显(输出节选,实测首尾;行首的容器日志前缀已略去):

Config loaded from bewcloud.config.ts {
  "auth": {
    "baseUrl": "http://192.168.146.128:8155",
    "allowSignups": false,
    "enableEmailVerification": false,
    "enableForeverSignup": true,
    "enableMultiFactor": false,
    "allowedCookieDomains": [],
    "skipCookieDomainSecurity": true,
    "enableSingleSignOn": false,
    "allowSignupsViaSingleSignOn": false,
    "singleSignOnUrl": "",
    "singleSignOnEmailAttribute": "email",
    "singleSignOnScopes": [
      "openid",
      "email"
    ]
  },
  "files": {
    "rootPath": "data-files",
    "allowPublicSharing": true,
    "allowDirectoryDownloads": true,
    "maxUploadSizeInMegabytes": 100
  },
  "core": {
    "enabledApps": [
      "dashboard",
      "files",
      "news",
      "notes",
      "photos",
      "expenses",
      "contacts",
      "calendar"
    ],
    "maxRequestSizeInMegabytes": 12
  },
  "visuals": {
    "title": "My own cloud",
    "description": "This is my own cloud!",
    "helpEmail": ""
  },
  "email": {
    "from": "help@bewcloud.com",
    "host": "localhost",
    "port": 465,
    "tlsMode": "auto",
    "tlsVerify": true
  },
  "contacts": {
    "enableCardDavServer": true,
    "cardDavUrl": "http://radicale:5232"
  },
  "calendar": {
    "enableCalDavServer": true,
    "calDavUrl": "http://radicale:5232"
  }
}

Listening on http://0.0.0.0:8000/ (http://localhost:8000/)
Crons starting...

首行证明 bewcloud.config.ts 被成功加载(而非回退默认),紧随的 JSON 是深合并后的全量生效配置——样例里只写了 6 个 auth 键,日志里 auth 域却有 12 个键,缺的就是落到默认值的键;JSON 之后的 Listening on 行说明服务已在配置生效后启动。

3.2 修改与重载方式

两类配置的重载方式不同:

配置修改文件生效方式原因
bewcloud.config.ts部署目录下同名文件docker compose restart website启动时一次性 import,进程内缓存
.env部署目录下同名文件docker compose up -d(重建服务)环境变量只在容器创建时注入,restart 不会重新读

改完配置后统一用 3.1 节的日志法核对生效值,再执行功能验证。

3.3 一个容易误判的点:默认值与样例值不同

官方 bewcloud.config.sample.ts 是「推荐起始值」,与源码 DEFAULT_CONFIG 的默认值并不完全一致(如 visuals.helpEmail 默认是 help@bewcloud.com,样例里是空串)。不写某键时的真实行为以第四节「默认值」列为准——本文默认值全部抄自 DEFAULT_CONFIG 源码,不是样例文件。

四、参数总览

bewcloud.config.ts 七域 30 项总览(默认值来源:lib/config.ts DEFAULT_CONFIG,2026-10-30 实查):

域参数类型默认值一句话作用
authbaseUrlstringhttp://localhost:8000对外访问基准地址,决定 Cookie 作用域与绝对链接
authallowSignupsboolfalse开放注册开关(首个用户不受限,见 5.1)
authenableEmailVerificationboolfalse注册后需邮箱验证
authenableForeverSignupbooltrue注册即长期有效(关闭则账号有有效期语义)
authenableMultiFactorboolfalse允许用户启用 MFA(TOTP/passkey)
authallowedCookieDomainsstring[][]额外允许携带 Cookie 的域列表
authskipCookieDomainSecurityboolfalse跳过 Cookie 安全域校验(HTTP+IP 访问必开)
authenableSingleSignOnboolfalse启用 OIDC 单点登录
authallowSignupsViaSingleSignOnboolfalse允许经 SSO 自动注册
authsingleSignOnUrlstring''OIDC 发现/授权地址
authsingleSignOnEmailAttributestringemail从 SSO 声明中取邮箱的字段名
authsingleSignOnScopesstring[]['openid', 'email']OIDC 请求的 scope
filesrootPathstringdata-files文件存储根目录(相对工作目录)
filesallowPublicSharingboolfalse公共分享链接开关
filesallowDirectoryDownloadsboolfalse目录打包(zip)下载开关
filesmaxUploadSizeInMegabytesnumber100单文件上传上限(MB),作用于 /dav 与 /api/files/upload
coreenabledAppsstring[]8 个应用全开启用的应用清单,首元素为登录落地页
coremaxRequestSizeInMegabytesnumber12除上传外的一般请求体上限(MB)
visualstitlestring''站点标题
visualsdescriptionstring''站点描述
visualshelpEmailstringhelp@bewcloud.com界面上展示的帮助邮箱
emailfromstringhelp@bewcloud.com发信 From 地址
emailhoststringlocalhostSMTP 主机
emailportnumber465SMTP 端口
emailtlsModestringautoTLS 模式(auto/starttls 等)
emailtlsVerifybooltrue校验 SMTP 证书
contactsenableCardDavServerbooltrue启用 CardDAV(联系人)
contactscardDavUrlstringhttp://radicale:5232CardDAV 后端地址(应用反代目标)
calendarenableCalDavServerbooltrue启用 CalDAV(日历)
calendarcalDavUrlstringhttp://radicale:5232CalDAV 后端地址(应用反代目标)

.env 变量总览见部署篇第六节(12 项),逐项详解并入本篇 5.8。

五、核心参数分类详解

5.1 auth 域:认证与注册(12 项)

auth 是 bewCloud 配置里最重的一个域,注册、会话、SSO 全在这里。

  • baseUrl(默认 http://localhost:8000):整个应用的对外基准地址。登录 Cookie 的作用域、SSO 回调地址(baseUrl + /oidc/callback)、页面里的绝对链接都由它派生。必须写成浏览器实际可达的地址——写成 localhost 而用 IP 访问,Cookie 作用域就对不上,登录静默失败。官方文档同时警告:非 HTTPS 场景认证受限(localhost 例外),这正是 skipCookieDomainSecurity 存在的原因。
  • allowSignups(默认 false):常规注册开关。关闭时注册页仍可访问,但提交会被拒——除非实例里还没有任何管理员。注册判定逻辑(源码 isSignupAllowed):allowSignups 为真,或「尚无管理员」时放行。所以首用户必然能注册并成为管理员,这是官方 README 明示的行为,实测确认。
  • enableEmailVerification(默认 false):开启后注册需收验证邮件,依赖 email 域的 SMTP 配置可用。内网无邮件服务的实例保持默认。
  • enableForeverSignup(默认 true):注册即激活 100 年(官方 FAQ 的表述),个人自托管场景保持默认即可。
  • enableMultiFactor(默认 false):允许用户在设置页启用 MFA。支持 TOTP(需 .env 配 MFA_KEY/MFA_SALT)与 passkey(v4.21.0 改进了 passkey 登录质询的服务端单次有效性)。
  • allowedCookieDomains(默认 []):多域名访问同一实例时,额外放行携带会话 Cookie 的域。默认空数组表示只用 baseUrl 对应的域。单域部署不需要动它。
  • skipCookieDomainSecurity(默认 false):跳过 Cookie 的安全域校验。HTTP + IP(或非 localhost 域名)访问必须设 true,否则登录态无法保持;官方注释还指出走 Cloudflare Tunnel 之类的反向代理时通常也需要。生产环境配好 HTTPS 后应设回 false。
  • enableSingleSignOn / allowSignupsViaSingleSignOn / singleSignOnUrl / singleSignOnEmailAttribute / singleSignOnScopes:OIDC SSO 五件套。enableSingleSignOn 打开后登录页出现 SSO 入口,回调地址是 baseUrl + /oidc/callback;allowSignupsViaSingleSignOn 独立于 allowSignups 控制「SSO 首次登录自动建号」;.env 侧需同步配 OIDC_CLIENT_ID/OIDC_CLIENT_SECRET。本篇实测未启用 SSO,配置取值见部署篇 4.3。

5.2 files 域:文件存储与分享(4 项)

  • rootPath(默认 data-files):文件存储根目录。相对路径相对应用工作目录解析(源码 getFilesRootPath:非绝对路径时 join(Deno.cwd(), rootPath)),容器形态下工作目录是 /app,所以默认落到 /app/data-files——这正是部署篇里把宿主 data-files/ 挂到 /app/data-files 的原因。改成绝对路径也可以,但要同步调整挂载。
  • allowPublicSharing(默认 false):公共分享链接总开关。关闭时分享接口直接不可用;开启后用户可对文件生成 /file-share/<id> 形式的公开链接。实测开启后分享上传文件成功。
  • allowDirectoryDownloads(默认 false):整目录打包 zip 下载开关。目录大时打包在应用进程内进行,低配实例建议保持关闭。
  • maxUploadSizeInMegabytes(默认 100):单文件上传上限,同时约束 WebDAV(/dav)与 API 上传(/api/files/upload)两条通道,大于 core.maxRequestSizeInMegabytes(12MB)属于预期——上传通道有独立限额。

5.3 core 域:应用开关与请求限额(2 项)

  • enabledApps(默认 8 个全开):['dashboard', 'files', 'news', 'notes', 'photos', 'expenses', 'contacts', 'calendar']。数组第一个元素是登录后的默认落地应用(想把文件页当首页就把它排第一);从数组移除的应用,入口与路由一并失效。置空会直接拒绝启动(源码校验:At least one app must be enabled. Please check the config.core.enabledApps array.)。
  • maxRequestSizeInMegabytes(默认 12):一般请求体上限,约束除文件上传外的一切请求。调大它不会放宽上传限额(上传走 files 域自己的值)。

5.4 visuals 域:站点外观(3 项)

title(默认空)、description(默认空)、helpEmail(默认 help@bewcloud.com)。三项纯展示:标题/描述出现在页面标题与 meta,帮助邮箱出现在界面帮助入口。公网实例建议把 helpEmail 改成实际维护邮箱。

5.5 email 域:发信通道(5 项)

from(默认 help@bewcloud.com)、host(默认 localhost)、port(默认 465)、tlsMode(默认 auto)、tlsVerify(默认 true)。功能触发点有两个:邮箱验证与(如启用)相关邮件通知。官方注释明确 tlsMode: auto 在 465 端口语义是「立即 TLS」,其它端口则是 starttls;自建内网 SMTP 不验证证书时可关 tlsVerify。未配 SMTP 时保持默认即可,功能不受影响(部署篇实测未配 SMTP 正常注册登录)。

5.6 contacts 域与 5.7 calendar 域:DAV 后端(各 2 项)

两组结构对称:enableCardDavServer/enableCalDavServer(默认均 true)控制入口是否暴露;cardDavUrl/calDavUrl(默认均 http://radicale:5232)指向 Radicale 后端。应用收到 /carddav/*、/caldav/* 请求后做认证代理,再转发到该地址。只有当你外置了独立 Radicale(或其他兼容 DAV 服务)时才改 URL;官方三服务编排下保持默认。.well-known/caldav、.well-known/carddav 发现端点由应用自动应答,无需配置。

5.8 .env 密钥类环境变量(12 项)

逐项语义与生产要求(样例值与生成方法见部署篇 4.2/六节):

变量语义与要点
PORT应用监听端口。改它要同步改 ports 映射右侧
POSTGRESQL_HOST/PORT数据库地址端口;编排内用服务名 postgresql:5432
POSTGRESQL_USER/PASSWORD/DBNAME数据库三元组;PASSWORD 必须与 postgresql 服务的 POSTGRES_PASSWORD 一致
POSTGRESQL_CAFILE数据库 TLS 的 CA 文件路径;内网明文连接留空
JWT_SECRET会话 JWT 签名密钥。换值会使全部已登录会话失效;泄露等于任何人可伪造登录,生产必须 openssl rand -hex 32
PASSWORD_SALT口令哈希盐。换值会使既有口令全部失效(无法登录);只在初始化前确定
MFA_KEY/MFA_SALTTOTP 密钥加密用的 key 与盐;启用 MFA 前配置
OIDC_CLIENT_ID/OIDC_CLIENT_SECRETSSO 客户端凭据;对应 auth 域 SSO 五件套
SMTP_USERNAME/SMTP_PASSWORD发信凭据;启用邮箱验证时必配

💡 技术拓展:JWT_SECRET 与 PASSWORD_SALT 的「换值后果」差异值得记住——JWT_SECRET 换掉只是把当前会话作废(用户重新登录即可),PASSWORD_SALT 换掉则所有存量口令哈希全部失配(只能走重置流程)。所以 PASSWORD_SALT 属于「初始化前必须定死」的参数,JWT_SECRET 属于「可轮换」的参数,泄漏应急时按此处理。

六、生产配置模板

6.1 个人低配 NAS 模板(适用:2GB 内存小主机、单用户/家庭、HTTP 内网访问)

const config: PartialDeep<Config> = {
  auth: {
    baseUrl: 'http://<内网IP或域名>:<端口>',
    allowSignups: false,
    enableForeverSignup: true,
    skipCookieDomainSecurity: true,   // HTTP 内网访问
  },
  files: {
    allowPublicSharing: false,        // 不对外分享就关掉
    maxUploadSizeInMegabytes: 512,    // NAS 盘大,放宽单文件上限
  },
  core: {
    enabledApps: ['files', 'dashboard', 'calendar', 'contacts', 'notes', 'photos'],
    maxRequestSizeInMegabytes: 12,
  },
};

要点:关掉用不到的应用(news/expenses)收窄攻击面;内存预算维持官方编排的三服务各 256MB;enabledApps 首元素选最常用的应用。磁盘按文件量规划,文件本体与数据库卷分盘存放。

6.2 小团队 HTTPS 反代模板(适用:4GB+ 内存、10 人内、经反向代理提供 HTTPS)

const config: PartialDeep<Config> = {
  auth: {
    baseUrl: 'https://cloud.example.com',   // HTTPS 域名
    allowSignups: false,
    enableEmailVerification: true,          // 有 SMTP 了,开邮箱验证
    enableMultiFactor: true,                // 允许用户启用 TOTP/passkey
    skipCookieDomainSecurity: false,        // HTTPS 场景关掉跳过开关
    enableSingleSignOn: true,               // 接入企业 IdP 时开启
    allowSignupsViaSingleSignOn: false,
    singleSignOnUrl: 'https://idp.example.com/.well-known/openid-configuration',
  },
  files: {
    allowPublicSharing: false,              // 团队场景默认不对外分享
    allowDirectoryDownloads: true,
    maxUploadSizeInMegabytes: 100,
  },
  email: {
    from: 'cloud@example.com',
    host: 'smtp.example.com',
    port: 465,
    tlsMode: 'auto',
    tlsVerify: true,
  },
};

要点:HTTPS 就位后 skipCookieDomainSecurity 必须回 false;.env 同步补 SMTP_USERNAME/SMTP_PASSWORD 与 OIDC_CLIENT_ID/OIDC_CLIENT_SECRET;反向代理侧把 /caldav、/carddav、/dav、/.well-known/* 一并转发到应用(DAV 客户端依赖 well-known 发现),并放宽代理的上传体积限制到与 maxUploadSizeInMegabytes 匹配。

七、常见问题

Q1:改了 bewcloud.config.ts 重启了,行为没变? 三步定位:① 看启动日志有没有 Config loaded from bewcloud.config.ts——没有就是文件语法错误,应用已回退默认配置(日志里会有 Error loading config from bewcloud.config.ts);② 有的话核对合并 JSON 里该键的生效值,确认改的键名/域没写错;③ 确认改后执行的是 docker compose restart website(配置文件挂载单文件,restart 即可重新 import)。

Q2:改了 .env 用 restart 重启,环境变量没变? 环境变量在容器创建时注入,restart 不重建容器。用 docker compose up -d 让 Compose 检测到 .env 变化并重建服务。

Q3:启动报 At least one app must be enabled? core.enabledApps 被写成了空数组。至少保留一个应用,且注意第一个元素是登录落地页。

Q4:HTTP + IP 访问登录失败,反复回到登录页? skipCookieDomainSecurity 未开或 baseUrl 与实际访问地址不一致。两个都核对:baseUrl 写浏览器地址栏里的地址,HTTP+IP 场景 skipCookieDomainSecurity: true(部署篇实测确认此组合可行,HTTPS 上线后记得收回)。

Q5:maxUploadSizeInMegabytes 调到 512 了,为什么普通接口还是限 12MB? 设计如此:上传通道(/dav 与 /api/files/upload)用 files 域的独立限额,其余请求用 core.maxRequestSizeInMegabytes。两者独立调整。

Q6:想换 Radicale 为外置独立 DAV 服务? 把 contacts.cardDavUrl/calendar.calDavUrl 指到新地址即可,但外置服务要自行解决认证(bewCloud 的代理注入信任编排内网,跨主机需要同等的安全边界)。官方编排是唯一被官方验证过的形态,变更前备份 data-radicale。

八、参考链接