HeyForm 3.0.6 配置参数详解
HeyForm 3.0.6 全量配置面实测:官方 .env.example 58 键 + 镜像内 dist/environments 默认值合并参数表,按必配/核心/分类可选组织,APP_DISABLE_REGISTRATION 改参→重建→验证→回滚闭环与 ALLOW_PRIVATE_OUTBOUND 私网 webhook 实测,附生产配置模板与 FAQ(实测日期 2026-11-01/02)。
HeyForm 3.0.6 配置参数详解
目标:把 HeyForm v3.0.6 的全部可配置面讲透——官方
.env.example(147 行、58 个键,2026-11-02 取回)+ 镜像内dist/environments/index.js默认值(逐行核对,2026-11-01)合并成全量参数表,按「必配 / 核心 / 分类可选」组织,并用实测演示「改参数 → 重建容器 → 验证生效 → 回滚」闭环。全部回显来自实测环境(v3.0.6 三容器栈,实测日期 2026-11-01/02)。部署方法见《HeyForm 3.0.6 Docker Compose 部署指南》。
一、配置载体与生效方式
| 项目 | 结论(实测) |
|---|---|
| 配置形式 | 纯环境变量,无配置文件挂载点;compose 的 environment: 段或同目录 .env 插值 |
| 权威来源 | 官方 packages/server/.env.example;默认值在镜像 /app/packages/server/dist/environments/index.js |
| 生效方式 | 改 env 后 docker compose up -d(compose 检测到定义变化会重建容器);进程启动时一次性读取,不支持热加载 |
| 公开回显 | GET /api/config(无鉴权)返回 homepageURL、注册开关、cookieDomain、各三方登录启用状态——验证配置是否生效的最快探针 |
| 必填项 | SESSION_KEY、FORM_ENCRYPTION_KEY、MONGO_URI(无默认值,缺失启动失败) |
二、必配参数(4 个)
| 参数 | 默认 | 说明 |
|---|---|---|
APP_HOMEPAGE_URL | 缺省拼 http://{APP_LISTEN_HOSTNAME}:{APP_LISTEN_PORT} | 对外访问根地址。派生 Cookie Domain、CORS 白名单、上传 origins、OAuth 回调前缀;改错直接导致登录态异常 |
SESSION_KEY | 无(必填) | 会话签名密钥,建议 openssl rand -hex 32;更换会使全部在线会话失效 |
FORM_ENCRYPTION_KEY | 无(必填) | 表单分享 token 的 AES 密钥(openForm 返回的加密串即由它生成)。上线后不可更换,否则已分发链接全部失效 |
MONGO_URI | 无(必填) | 如 mongodb://mongo:27017/heyform;带认证时加 ?authSource=admin 并配 MONGO_USER/MONGO_PASSWORD |
三、核心运行参数(有合理默认)
| 参数 | 默认值 | 说明 |
|---|---|---|
NODE_ENV | development | 生产设 production |
APP_LISTEN_HOSTNAME | 0.0.0.0 | 监听地址 |
APP_LISTEN_PORT | 9157(源码 +process.env.APP_LISTEN_PORT || 9157) | 容器内端口;compose 映射右值必须是它(官方文档样例的 8000 已过时) |
CORS_ALLOWED_ORIGINS | 取 APP_HOMEPAGE_URL | 逗号分隔多源 |
TRUST_PROXY | false | 官方 .env.example 新增项:仅在可信反代后设置,防止伪造转发头 |
ENABLE_GOOGLE_FONTS | true | 表单主题引用 Google 字体;国内环境建议 false |
ALLOW_PRIVATE_OUTBOUND | false | webhook/图片代理是否允许访问私网地址,默认 fail-closed(SSRF 防护,DNS pinning + 私网段拦截) |
四、认证与账号
| 参数 | 默认 | 说明 |
|---|---|---|
APP_DISABLE_REGISTRATION | false | 关闭自助注册(实测闭环见第六节) |
DISABLE_LOGIN_WITH_PASSWORD | false | 关闭密码登录/注册,须先配好三方登录 |
SESSION_MAX_AGE | 15d | 会话寿命;实测登录回显 Max-Age=1296000 即 15 天 |
COOKIE_MAX_AGE | 1y | 记住类 Cookie |
COOKIE_DOMAIN | 取 APP_HOMEPAGE_URL 主机名 | 实测回显 Domain=192.168.1.172 |
BCRYPT_SALT | 10 | 密码哈希轮数 |
VERIFY_USER_EMAIL | true | 注册需邮箱验证码。没配 SMTP 必须改 false,否则官方 .env.example 原文警告「nobody can finish signing up」 |
VERIFICATION_CODE_EXPIRE / LIMIT | 10m / 5 | 验证码有效期/尝试上限 |
VERIFY_EMAIL_RESEND_COOLDOWN / DAILY_LIMIT | 60s / 20 | 重发节流(/api/config 实测回显 cooldown) |
INVITE_CODE_EXPIRE_DAYS | 7 | 团队邀请码 |
ACCOUNT_DELETION_SCHEDULE_INTERVAL | 2d | 注销账号清理周期 |
五、分类可选参数
5.1 三方登录(要素配齐才启用,/api/config 可见状态)
- Google:
GOOGLE_LOGIN_CLIENT_ID+GOOGLE_LOGIN_CLIENT_SECRET(两者齐全才启用,否则disableLoginWithGoogle:true——实测默认态即如此)。 - Apple:
APPLE_LOGIN_TEAM_ID/WEB_CLIENT_ID/KEY_ID/PRIVATE_KEY_PATH四项齐全。 - OIDC SSO:
OIDC_ISSUER/CLIENT_ID/CLIENT_SECRET三要素 +OIDC_DISPLAY_NAME=SSO、OIDC_DISPLAY_ICON_URL=''、OIDC_CLIENT_AUTH_METHOD=client_secret_basic、OIDC_ALLOW_PROVISIONING=false(APP_DISABLE_REGISTRATION=true时仍允许 OIDC 首登建号);回调 URL 为${APP_HOMEPAGE_URL}/connect/oidc/callback。
5.2 存储与上传
| 参数 | 默认 | 说明 |
|---|---|---|
UPLOAD_FILE_SIZE | 10mb | 单文件上限 |
UPLOAD_FILE_TYPES | 常见 MIME 集 | .env.example 示例为扩展名串 .jpg,.png,...,.7z |
S3_ENDPOINT/REGION/BUCKET/ACCESS_KEY_ID/SECRET_ACCESS_KEY/PUBLIC_URL | 可选 | 配齐则上传走 S3,否则本地 assets/ 卷 |
UNSPLASH_CLIENT_ID | 可选 | 图库背景 |
5.3 邮件(SMTP)
SMTP_HOST/PORT/USER/PASSWORD/FROM(可选),SMTP_SECURE=false、SMTP_SERVERNAME=null、SMTP_IGNORE_CERT=false。不配则注册验证码、邀请、找回密码不可用。
5.4 MongoDB / Redis
| 参数 | 默认 | 说明 |
|---|---|---|
MONGO_USER / MONGO_PASSWORD | 可选 | 配合 authSource |
MONGO_SSL_CA_PATH | 可选 | 内容为 CA 文件路径(读文件内容) |
REDIS_HOST / REDIS_PORT / REDIS_DB | 127.0.0.1 / 6379 / 0 | compose 内指向 keydb |
REDIS_USERNAME / REDIS_PASSWORD / REDIS_TLS | 可选 | REDIS_TLS 为 JSON 对象串(ioredis TLS options),{} 即启用默认 TLS |
5.5 队列与任务(Bull,跑在 Redis 上)
BULL_JOB_ATTEMPTS=3、BULL_JOB_TIMEOUT=1m、BULL_JOB_BACKOFF_DELAY=3000、BULL_JOB_BACKOFF_TYPE=fixed。webhook 投递重试即受此控:实测失败记录 maxAttempts:3、willRetry 按尝试次数翻转。
5.6 集成与加密
INTEGRATION_ENCRYPTION_KEY/INTEGRATION_ENCRYPTION_KEY_PREVIOUS:加密集成凭据(OAuth token、API key)。不配则需凭据的集成不可用(webhook 除外);轮换流程写在 .env.example 注释中:双键并存重启 → 跑reencrypt-integration-secretsCLI → 删旧键(CLI 实测见《常用 CLI 命令与工具详解》)。与FORM_ENCRYPTION_KEY分离,互不影响。- OAuth 集成客户端:
GOOGLE_INTEGRATION_CLIENT_ID/SECRET(Google Sheets),回调${APP_HOMEPAGE_URL}/api/integrations/oauth/callback;未配的 provider 在 UI 中隐藏。
5.7 反垃圾与提交
AKISMET_KEY、GOOGLE_RECAPTCHA_KEY/SECRET(可选);DISABLE_SUBMISSION_IP=false(true 则不存 IP,改哈希限流);FORM_REPORT_RATE=5s(举报频率);提交列表 limit 上限 30(实测超限报 limit must not be greater than 30)。
5.8 AI 与支付
OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_GPT_MODEL(默认 gpt-3.5-turbo-0125)驱动 createFormWithAI;STRIPE_PUBLISHABLE_KEY/SECRET_KEY/CONNECT_CLIENT_ID/WEBHOOK_SECRET_KEY/STRIPE_VERSION 启用收款表单。
六、改参 → 重启 → 验证 → 回滚闭环(2026-11-02 实测)
以 APP_DISABLE_REGISTRATION 为例,全程逐字回显:
# 1. 基线:注册开放
$ curl -X POST http://localhost:8150/graphql -H 'Content-Type: application/json' \
-H "x-device-id: <新uuid>" -d '{"query":"mutation { signUp(input: {name:\"t1\", email:\"test1@heyform.local\", password:\"Q1w2e3r4\"}) }"}'
{"data":{"signUp":true}}
# 2. compose 的 environment 段加入:APP_DISABLE_REGISTRATION: 'true'
$ docker compose up -d heyform
Container heyform-306-server Started # compose 检测到 env 变化,重建容器
# 3. 公开探针确认生效
$ curl -s http://localhost:8150/api/config | jq .appDisableRegistration
appDisableRegistration = True
# 4. 行为验证:注册被拒
$ curl ... signUp(test2@heyform.local)
{"errors":[{"code":"BAD_REQUEST","message":"Error: Registration is disabled"}],"data":null}
# 5. 回滚:删除该行 → 重建 → 探针 False → signUp 恢复 true
$ docker compose up -d heyform
appDisableRegistration = False
{"data":{"signUp":true}}
第二组闭环(前任 2026-11-01 实测):ALLOW_PRIVATE_OUTBOUND 默认态下给 webhook 集成配私网 URL 被拒 BAD_REQUEST "Private network URLs are not allowed";compose 加 ALLOW_PRIVATE_OUTBOUND: 'true' 重建后,同一 mutation 返回 {"updateIntegrationSettings":{"endpointUrl":"http://192.168.1.172:18888/hook"}},宿主接收器实际收到提交回调 payload。
七、生产配置模板
environment:
NODE_ENV: production
APP_HOMEPAGE_URL: https://form.example.com # 与反代域名一致
TRUST_PROXY: 1 # 按反代拓扑取 Express 值
SESSION_KEY: <openssl rand -hex 32>
FORM_ENCRYPTION_KEY: <openssl rand -hex 32> # 上线后永不更换
INTEGRATION_ENCRYPTION_KEY: <openssl rand -base64 32>
MONGO_URI: 'mongodb://mongo:27017/heyform?authSource=admin'
MONGO_USER: root
MONGO_PASSWORD: <强口令>
REDIS_HOST: keydb
REDIS_PORT: 6379
APP_DISABLE_REGISTRATION: 'true' # 关闭自助注册
ENABLE_GOOGLE_FONTS: 'false' # 国内环境
SMTP_HOST/PORT/USER/PASSWORD/FROM: <企业邮箱> # 或 VERIFY_USER_EMAIL=false
ALLOW_PRIVATE_OUTBOUND: 'true' # 仅当 webhook 目标是内网且可信
必改清单:APP_HOMEPAGE_URL、两个 *_KEY、MONGO_PASSWORD、APP_DISABLE_REGISTRATION;按需:SMTP、OIDC、S3。
八、FAQ
- 改 env 后没生效?
docker compose up -d只在定义变化时重建;确认docker inspect heyform-306-server --format '{{json .Config.Env}}' | grep 参数名,再docker compose up -d --force兜底。 - 能换
FORM_ENCRYPTION_KEY吗? 会让所有已发布表单的分享 token 失效,等于链接全部重发;规划期就固定。 SESSION_KEY泄露怎么办? 更换后旧会话失效、需重新登录,无数据损失;与INTEGRATION_ENCRYPTION_KEY的轮换(需跑 CLI)不同。- 三方登录按钮没出现? 对应要素没配齐(见 5.1),
/api/config的disableLoginWith*是最快判据。 - webhook 打不到内网服务? 默认 fail-closed,设
ALLOW_PRIVATE_OUTBOUND=true(有 SSRF 风险,仅可信环境)。
关联文章:部署与端口口径见《HeyForm 3.0.6 Docker Compose 部署指南》;CLI 运维与凭据轮换工具见《HeyForm 3.0.6 常用 CLI 命令与工具详解》。