Puter 26.10.1 配置参数详解
Puter 26.10.1 配置参数详解:两层加载机制实测、70 个参数键九大功能域逐一详解(含镜像内置默认值与官方注释要点)、disable_user_signup 生效链路实证与 8-16GB 单机生产配置模板。
Puter 26.10.1 配置参数详解
目标:系统讲解 Puter 26.10.1 的配置体系——
config.json的两层加载机制、全部 70 个参数键的分组详解(含镜像内置默认值)、自托管必改项与生产配置模板,并对关键开关逐一实测验证。已在 Ubuntu 24.04 单机实测环境(Docker Compose 部署,见 《Puter Docker Compose 部署指南》)验证通过。
一、环境信息
- 实测环境:Ubuntu 24.04.5 LTS(x86_64),Docker 29.9.2 + Compose v5.6.1
- Puter 版本:26.10.1(镜像
ghcr.io/heyputer/putermain 标签同源构建,补 sharp 依赖) - 配置来源权威依据:镜像内置默认配置
/opt/puter/config.default.json、官方完整参数模板config.template.jsonc(仓库 main 分支,2026-11-01 取证)、字段级定义src/backend/types.ts(官方注释指认的唯一事实源) - 主应用配置文件(本文实测服务器路径):
/opt/puter/puter/config/config.json(挂载到应用内/etc/puter/config.json)
💡 说明:Puter 的参数体系分两层——镜像内置的
config.default.json(OSS 默认,面向开发/单机)与运维提供的config.json(覆盖层)。本文所有「默认值」均从实测的 default 文件与官方 template 注释取证,非转述。
二、前置条件
- 已按 《Puter Docker Compose 部署指南》 部署完成一套在跑的 Puter 栈(本文的修改与验证均在该栈上实操);
- 能编辑宿主
puter/config/config.json并执行docker compose restart puter; - 了解 JSON 语法(Puter 配置为纯 JSON,不支持注释;官方 template 里的注释仅供阅读,拷贝使用时须剥掉)。
三、参数查看与修改方式
3.1 两层加载机制(实测回显)
主应用每次启动时先加载镜像内置默认,再用运维配置覆盖,日志明确打印两层来源:
[config] defaults from /opt/puter/config.default.json
[config] override from /etc/puter/config.json
含义与结论:
/opt/puter/config.default.json是镜像内只读默认(config_name: "oss-default"),含开发期密钥占位(dev-jwt-secret-v2-change-me)与 SQLite/本地模拟存储等开发取向默认;/etc/puter/config.json是唯一运维入口,每个键只在一个规范位置生效,没有别名回退(官方 template 注释原话:Each setting lives at exactly one canonical key — there are no fallback aliases);- 未在 config.json 出现的键一律落到 default 值,因此最小配置可行(部署指南 4.2 节即是最小可用集)。
3.2 修改与生效流程
改 config.json 后必须重启主应用(进程只在启动时读一次配置):
cd /opt/puter # compose 项目目录
vim puter/config/config.json
docker compose restart puter
# 实测输出:
# Container puter-26.10.1-app Restarting
# Container puter-26.10.1-app Started
重启后 30~60 秒服务恢复,验证:
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8140/
# 实测输出(就绪后):
# 200
docker compose logs --since 2m puter | grep -E 'fully booted'
# 实测输出:
# puter-26.10.1-app | PuterServer has fully booted.
3.3 配置生效实证:以 disable_user_signup 为例
用注册开关做一轮完整实测(改配置 → 重启 → 验证 → 还原),确认配置链路真实生效。把 "disable_user_signup": true 写入 config.json 并重启后,调用注册接口:
curl -s -X POST http://localhost:8140/signup \
-H 'Content-Type: application/json' \
-d '{"username":"newuser1","email":"newuser1@puter.localhost","password":"q1w2e3r4"}'
# 实测输出(开关打开时):
# {"error":"User registration is disabled.","message":"User registration is disabled.","code":"signup_disabled"}
# (HTTP 403)
删除该键恢复默认(false)并重启后,同一请求恢复正常的注册/用户名冲突响应——证明该键从 config.json 到接口行为的全链路生效。其余参数的生效方式相同。
四、参数总览
config.json 全部参数键按功能域分组(键数以官方 template 全量 70 键计;⚡ 标记为自托管必查项):
| 功能域 | 参数键 |
|---|---|
| 环境与身份 | config_name、env、log_format、version、serverId |
| 网络与域名路由 | ⚡domain、⚡protocol、⚡pub_port、port、origin、api_base_url、⚡static_hosting_domain(_alt)、⚡private_app_hosting_domain(_alt)、keep_alive_timeout、allow_all_host_values、allow_no_host_header、allow_nipio_domains、custom_domains_enabled、enable_ip_validation、trust_proxy、no_browser_launch |
| 认证与会话 | ⚡jwt_secret_v2、⚡url_signature_secret、cookie_name、min_pass_length、disable_user_signup、allow_system_login、strict_email_verification_required、captcha、oidc |
| 用户与目录 | default_user_group、default_temp_group、enable_public_folders |
| 对象存储 | ⚡s3、⚡s3_bucket、s3_region、region、storage_capacity、is_storage_limited、available_device_storage、thumbnailStore |
| 数据库 | ⚡database |
| KV 存储 | ⚡dynamo |
| 缓存 | ⚡redis |
| 邮件 | email、userEmail、share_email_notifications |
| 分享限额 | share_daily_limit、share_notify_limits |
| 团队 | teams_enabled、max_teams_per_user、max_seats_per_team_free、max_seats_per_team_paid、max_seats_per_team、teams_allowed_email_domains |
| 通知与告警 | notificationRetentionDays、notificationAckTimeoutMs、pager |
| 限流 | rate_limit |
| AI 提供商 | ⚡providers(30+ 个提供商键) |
| GUI 与前端 | gui_assets_root、gui_profile、builtin_apps、use_bundled_gui、gui_bundle、gui_css、gui_puterjs_bundle、gui_params、native_apps_root、client_libs_root、puterjs_root |
| 特性开关 | feature_flags |
| 安全与杂项 | ⚡blockedEmailDomains、support_email、reserved_words、max_subdomains_per_user、server_health、extensions |
| 计量与预算 | ⚡unlimitedMetering、meteringEnforcement、meteringRetentionMonths、maxGlobalUsagePerMinute |
| 开发热加载 | no_devwatch、devwatch |
💡 技术拓展:自托管配置系统常见的三种加载方式对比——
方式 原理 代表 环境变量注入 全部参数摊平成 KEY=VALUEMinIO、Gitea 单配置文件 + 覆盖层 默认文件 + 运维文件两层合并 Puter(default.json + config.json) 数据库存配置 参数入库,界面热改 WordPress、Nextcloud(部分) Puter 采用「单文件覆盖层」:默认值进镜像、运维差异收敛到一个 config.json,改后重启生效。无热加载是有意取舍——配置含密钥与会话安全项,进程内缓存避免半旧状态。
五、核心参数分类详解
5.1 环境与身份
env(默认"dev"):dev会开浏览器、跳过一次性邮箱域检查、启用 webpack 热加载;prod直接服务预构建产物。自托管必须显式设"prod"(部署指南的最小配置已含)。实测镜像 default 为dev,部署指南配置覆盖为prod。log_format(默认text):设为json时全局 console 被替换,每条日志一行结构化 JSON(level/timestamp/msg/请求 trace id),官方注释明确这是为日志采集器设计——一条调用一行事件,行式采集器不会把堆栈拆散,且支持按级别过滤。接入 ELK/Loki 时开启。serverId(默认无):本节点稳定身份,用于告警路由与优雅停机协调。多实例部署时每个节点给唯一值。config_name/version:纯标识字段,默认template/0.0.0,无行为影响。
5.2 网络与域名路由
port(默认4100):主应用内部监听端口,容器编排里 Caddy 反代到这个口。一般不改。pub_port(默认4100):对外呈现端口。反代场景必须改成用户浏览器实际访问的端口——本文实测环境 Caddy 映射宿主 8140,因此"pub_port": 8140;生产 80/443 直出时对应改 80 或 443。它影响生成出来的链接与预签名 URL。domain(默认puter.localhost):主访问域。生产改你的域名;单机体验保留 localhost 系列即可(浏览器对*.localhost自动回环解析)。origin/api_base_url:完整的对外 URL 与 API 子域基址,不设时按 protocol/domain/pub_port 自动推导。官方注释说明api_base_url用于构造签名 URL 并由 installedApps/whoami 扩展暴露给客户端。static_hosting_domain(默认site.puter.localhost)与static_hosting_domain_alt(默认host.puter.localhost):用户静态站点的访问域与备用域;private_app_hosting_domain(默认app.puter.localhost)与_alt(默认dev.puter.localhost):托管应用运行域。生产部署四个都要换成你的域名子域,并要求通配符 DNS。keep_alive_timeout(默认920000ms):HTTP 空闲连接保活时长。官方注释给出一个关键约束:必须大于前方任何代理的空闲超时,否则代理复用本服务已关闭的连接,客户端看到偶发 502。前置 nginx 时需联动检查其keepalive_timeout。allow_all_host_values(默认true)与allow_no_host_header(默认true):Host 头宽容开关,官方注明这是「dev-friendly 默认,公网安装应收紧」——生产建议false+ 显式信任域,防止 Host 头伪造路由。custom_domains_enabled(默认false):是否允许用户绑定自定义域名到托管站点;allow_nipio_domains(默认false):是否放行 nip.io 类泛解析服务域。trust_proxy(镜像默认false):Express 信任代理跳数。官方注释的硬性安全结论:生产严禁设true(信任每一跳,X-Forwarded-For 可伪造);应为代理层数(Caddy 单层 =1,Cloudflare→ALB→app =2)或 CIDR。部署指南实测配置即"trust_proxy": 1。
5.3 认证与会话
jwt_secret_v2/url_signature_secret(镜像默认dev-jwt-secret-v2-change-me/dev-url-signature-secret-change-me):会话 JWT 签名密钥与对象存储预签名 URL 签名密钥。官方注释大写警告:任何公开部署必须用openssl rand -hex 64换掉。轮换后果:所有已登录会话与已发出的预签名 URL 立即失效。cookie_name(默认puter_auth_token):会话 Cookie 名,无冲突不用改。min_pass_length(默认6):密码最小长度。生产建议 8~12;官方 self-hosting 文档示例用 12。disable_user_signup(默认false):关闭后匿名访客只能登录不能注册(3.3 节实测 403signup_disabled)。内部部署配 OIDC 时建议关闭原生注册。allow_system_login(默认false):是否允许登录内置system账户。默认关闭,实测保持关闭(源码里 system 用户无此开关时一律返回 404 Username not found)。strict_email_verification_required(默认false):开启后未验证邮箱不能登录——只在配好 SMTP 后才有意义,否则会把所有用户锁在门外。captcha:{"enabled": false, "difficulty": "medium"}。内置 Proof-of-Work 验证码(无需外部服务),difficulty可选easy/medium/hard。公网注册开放时建议开启。oidc.providers:第三方登录。Google 走 OIDC discovery 只需 client_id/secret/scopes;自定义提供商须另给authorization_endpoint/token_endpoint/userinfo_endpoint;Apple 还需 team_id/key_id/p8 私钥;Microsoft 需 tenant_id(common放行个人+组织)。回调地址统一为https://<你的域名>/auth/oidc/callback/login(注册为/signup)。
5.4 存储与数据库
s3:文件实体存储。两种形态二选一(官方注释:每个键只有一个规范位置)——s3.localConfig:内置进程内 S3 兼容实现(fauxqs,开发/默认 Docker 模式),文件落dataDir本地目录;s3.s3Config:真实/外部 S3 兼容存储。实测部署用的是这个形态:
"s3": {
"s3Config": {
"endpoint": "http://s3:9000",
"publicEndpoint": "http://s3.puter.localhost",
"accessKeyId": "puter",
"secretAccessKey": "<与 .env 的 S3_SECRET_KEY 一致>",
"region": "us-east-1",
"forcePathStyle": true
}
}
关键子键:publicEndpoint 是浏览器侧预签名 URL 用的端点——服务端端点(容器内 http://s3:9000)浏览器不可达时必须设置;forcePathStyle 对 RustFS/MinIO 必须为 true(路径风格寻址),真实 AWS S3 则保持 false(虚拟主机风格)。
s3_bucket(默认puter-local):文件实体桶名,与 s3-init 任务建的桶一致。storage_capacity(默认104857600= 100 MB)与is_storage_limited(默认false):单用户配额与配额开关。默认不限量(受磁盘约束);要限额时两者配合,如 5 GiB =5368709120+true。注意语义:这是「默认配额」,不是总量池。database:engine可选sqlite(默认,单机/开发)/mysql(MariaDB,生产推荐)/postgres(社区贡献,官方注释明示非生产路径、可能有未移植 SQL 方言,生产自托管以 mysql 与 sqlite 为受支持默认)。mysql 形态的完整实测配置见部署指南 4.2 节;migrationPaths指向镜像内迁移目录且幂等,可常开。postgres 另支持connectionString一体化连接串与replica读副本池(读流量路由)。dynamo:KV 存储(puter.kv 底层)。endpoint指本地 dynamodb-local 时配bootstrapTables: true首启建表——官方注释警告:对真实 AWS 绝不能开,表应走 IaC 预建。凭据子对象是 snake_case(access_key/secret_key,与 s3 的 camelCase 不同,官方注释特意标注此差异);dynamodb-local 任意非空值即可(实测用fake/fake)。redis:缓存与跨节点限流。useMock: true为进程内 mock(开发/单节点默认);自托管容器用startupNodes指向 Valkey/Redis——客户端按 cluster 协议连接,单容器也要以 cluster 模式跑(部署指南编排已处理);tls默认 true(匹配生产 ElastiCache),自托管明文 Valkey 必须显式false。
5.5 邮件
email(Nodemailer 事务邮件传输):用于密码重置/邮箱确认。不配时首启日志提示[email] no email transport configured — send() will fail until configured(实测日志原文),相关流程静默失败。配 SMTP 后share_email_notifications(默认 on)即生效:分享给已有账户的收件人时同时发邮件,可用邮件内退订链接退出;设false仅站内通知。userEmail(进阶收信):给每个账户开@你的域名邮箱。secret是/email/ingress入口 gates(未设则该端点不存在,实测日志[useremailrx] config.userEmail.secret unset - email ingress disabled);localServer: true由独立 SMTP 进程接收外部邮件;官方注释以显著篇幅警告该监听天生无认证、无垃圾/SFP/DKIM/DMARC 过滤,暴露公网前必须前置过滤中继。strict_email_verification_required与 5.3 节联动:要求先验证邮箱才能登录。
5.6 分享与团队
share_daily_limit(默认 200):单账户每日新建分享数上限。share_notify_limits:分享「打扰」收件人的频率约束(站内推送+邮件),含pairWindowSeconds(900)、pairDaily(20)、recipientHourly(10)、recipientDaily(50)、emailBatchSeconds(90)——超预算分享仍成功,只丢弃打扰;非正值移除约束。teams_enabled(默认false):团队功能总闸,官方注释明确关闭时/teams路由根本不注册(而非注册后拒绝),关闭即完全回退不动数据。max_teams_per_user(默认 1)/max_seats_per_team_free(默认 3)/max_seats_per_team_paid(默认 40):团队数与席位上限;无计费部署可用max_seats_per_team一刀切覆盖两者。
5.7 通知与告警
notificationRetentionDays(默认 0=永久):通知保留天数,>0 启用清扫。pager:系统告警路由。severityOverrides可不改代码调级或静音告警(键为告警 id 或前缀*模式);两个传输默认都关——pagerduty(minSeverity默认 warning,info 不进呼叫系统)与slackwebhook(repeatThrottleMs默认 900000ms 节流重发)。自托管单节点默认行为 = 告警只打控制台日志。
5.8 限流
rate_limit.backend(默认 redis):三选一——memory(单节点)、redis(多节点,经 Valkey 共享计数器)、kv(DynamoDB 计数器)。容器部署保持默认 redis。
5.9 AI 提供商(providers)
任何配了 key 的提供商自动启用(官方注释:Any provider with a key set is auto-enabled)。实测配置禁用本地 Ollama 探测("providers": {"ollama": {"enabled": false}})——官方注释说明不显式关闭时启动会因探测 Ollama 打 ECONNREFUSED。全量提供商清单(chat/completion):claude、openai-completion、azure-openai、gemini、meta、groq、deepseek、mistral、xai、moonshot、minimax、openrouter、infron、byteplus、kling、zai、alibaba、hoonify、together-ai、ollama;图像:openai/gemini/together/cloudflare/xai-image-generation;视频:together/gemini-video-generation;语音与 OCR:openai(whisper/TTS)、elevenlabs、aws-polly、speechify、aws-textract、mistral-ocr。注意三类凭据形态:多数用 apiKey;AWS 系(polly/textract)用 snake_case access_key/secret_key(或 useCredentialChain: true);cloudflare 图像用 apiToken+accountId。
⚠️ 安全边界:提供商 API Key 属系统级真实密钥,config.json 里明文落盘需配合文件权限(
chmod 600)与磁盘访问控制;更稳妥的方式是平台通用做法——值用${ENV_VAR}引用环境变量注入。
5.10 GUI 与前端
自托管通常只碰三个:gui_params(改桌面标题/描述/分享图,如 "title": "公司私有云");use_bundled_gui(prod 环境默认用打包产物,保持默认即可);gui_puterjs_bundle(默认官方 CDN https://js.puter.com/v2/,内网隔离环境可指向本地构建)。其余(gui_assets_root/gui_profile/bundle 路径)为源码开发参数,容器部署不动。
5.11 安全与杂项
blockedEmailDomains(默认[]):注册/绑邮箱拒绝的一次性邮箱域(后缀匹配含子域),如["mailinator.com","tempmail.com"]。reserved_words(默认[]):用户/子域名不可抢注的保留词。实测发现root、admin等在默认部署即受保护(注册 root 返回username_already_in_use,登录则 Username not found——保留字被系统占用但非真实账户)。max_subdomains_per_user(默认 10):用户可建托管子域上限。server_health:健康探测阈值(db_liveness_latency_fail_ms默认 1500ms 数据库活性延迟线)。extensions(默认["./extensions"]):扩展扫描目录;首启日志逐个 Importing extensions/*.js(appTelemetry/devWatcher/installedApps/metering/thumbnails/useremailrx/whoami/workerSandbox,实测日志原文)。feature_flags:扁平布尔包,默认仅服务端可见,白名单内的键才暴露给客户端。
5.12 计量与预算(自托管必查)
unlimitedMetering(默认false):设 true 后所有账户按无限额度解析——用量照记(仪表盘可见)但永不因额度拒绝。官方注释直接点名自托管场景:没有地方充值却按免费月度额度(0.5 美元量级)约束,用户超额度后 AI、文件传输、KV 接口开始返回 402insufficient_funds。自托管强烈建议 true。meteringEnforcement:细粒度执法开关{enabled, workers, subscriptions}——enabled:false保留记账但不拦截;workers默认 false(worker 驱动的调用豁免拦截,因其无提示界面可弹);subscriptions:false用于无付费计划部署(否则供应商兼容 AI 端点对全部账户拒绝)。meteringRetentionMonths(默认 3):月度用量记录保留月数,0 = 永久;变更只影响之后写入的记录。maxGlobalUsagePerMinute:全节点每分钟支出费率告警线(微美分/分钟),默认关闭;官方注释提醒该值必须实测推导,过时数值会对健康增长误报。
六、生产配置模板
适用场景:816 GB 内存、NVMe SSD、2050 人内网团队或个人公网自建,MariaDB + RustFS 全栈单机。在部署指南 4.2 节最小配置基础上叠加生产项(密钥值以生成命令替代,不落明文):
{
"domain": "puter.example.com",
"protocol": "https",
"pub_port": 443,
"env": "prod",
"log_format": "json",
"serverId": "puter-node-1",
"static_hosting_domain": "site.puter.example.com",
"static_hosting_domain_alt": "host.puter.example.com",
"private_app_hosting_domain": "app.puter.example.com",
"private_app_hosting_domain_alt": "dev.puter.example.com",
"allow_all_host_values": false,
"allow_no_host_header": false,
"jwt_secret_v2": "${JWT_SECRET_V2}",
"url_signature_secret": "${URL_SIGNATURE_SECRET}",
"min_pass_length": 10,
"disable_user_signup": true,
"captcha": { "enabled": true, "difficulty": "medium" },
"oidc": {
"providers": {
"google": {
"client_id": "${OIDC_GOOGLE_CLIENT_ID}",
"client_secret": "${OIDC_GOOGLE_CLIENT_SECRET}",
"scopes": "openid email profile"
}
}
},
"database": {
"engine": "mysql",
"host": "mariadb",
"port": 3306,
"user": "puter",
"password": "${MARIADB_PASSWORD}",
"database": "puter",
"migrationPaths": ["/opt/puter/dist/src/backend/clients/database/migrations/mysql"]
},
"redis": {
"startupNodes": [{ "host": "valkey", "port": 6379 }],
"tls": false
},
"dynamo": {
"endpoint": "http://dynamo:8000",
"bootstrapTables": true,
"aws": { "access_key": "fake", "secret_key": "fake", "region": "us-east-1" }
},
"s3": {
"s3Config": {
"endpoint": "http://s3:9000",
"publicEndpoint": "https://s3.puter.example.com",
"accessKeyId": "puter",
"secretAccessKey": "${S3_SECRET_KEY}",
"region": "us-east-1",
"forcePathStyle": true
}
},
"s3_bucket": "puter-local",
"s3_region": "us-east-1",
"storage_capacity": 107374182400,
"is_storage_limited": true,
"providers": { "ollama": { "enabled": false } },
"unlimitedMetering": true,
"meteringEnforcement": { "subscriptions": false },
"trust_proxy": 1
}
模板要点解读:
- 密钥全部
${VAR}化:JWT/签名/OIDC/数据库/S3 密钥不落明文,由.env或外部密钥管理注入后以环境变量引用;仅 dynamodb-local 的fake占位凭据无敏感性可明文。 - 公网收紧三件套:
allow_all_host_values/allow_no_host_header关闭 +captcha开启 +disable_user_signup: true(配 OIDC 统一入口)。 - 配额示例:
storage_capacity: 107374182400(100 GiB/用户)+is_storage_limited: true;不改则全量共享磁盘。 unlimitedMetering: true是自托管与 puter.com 托管最大的配置分歧点,忘配是最常见的「用着用着 402」根因。- TLS 形态:
protocol: https+pub_port: 443对应 Caddy 挂通配符证书(证书文件放置与 Caddyfile 的 443 块启用见 《Puter Docker Compose 部署指南》第八节挂载表)。
七、常见问题
Q1:改了 config.json 不生效
进程只在启动时读配置。执行 docker compose restart puter 并确认日志出现 PuterServer has fully booted.(实测回显见 3.2 节)后再验证。
Q2:注册接口返回 403 signup_disabled
disable_user_signup 已开启(3.3 节实测该开关生效链路)。内部部署属预期;开放注册需删除该键或设 false 并重启。
Q3:用户操作陆续返回 402 insufficient_funds
计量额度用尽(见 5.12 节)。加 "unlimitedMetering": true 重启即解;用量记录仍可在界面查看。
Q4:上传下载报签名/跨域错误
s3.publicEndpoint 与浏览器实际访问域不一致,或桶 CORS 缺失。前者改 publicEndpoint 为公网可达域;后者确认 s3-init 任务成功执行过(部署指南编排含 CORS 写入)。
Q5:日志反复出现 ECONNREFUSED 11434
未配 Ollama 但未显式禁用探测。加 "providers": {"ollama": {"enabled": false}}(官方注释明示的启动探测行为)。
Q6:公网部署后客户端 IP 全是反代地址
trust_proxy 未按代理层数设置。Caddy 单层设 1;严禁 true(5.2 节官方安全结论)。
八、参考链接
- 官方完整参数模板:https://github.com/HeyPuter/puter/blob/main/config.template.jsonc
- 字段级事实源:仓库
src/backend/types.ts - 官方自托管文档(配置章节):https://github.com/HeyPuter/puter/blob/main/doc/self-hosting.md
- 本专栏相关篇目:《Puter 介绍与选型指南》、《Puter Docker Compose 部署指南》、《Puter 26.10.1 API 使用详解》