ClearFlask 2.7.2 配置参数详解
ClearFlask 2.7.2 self-host 配置体系全解:config-selfhost.cfg 语法与域名/注册/数据源/搜索引擎/对象存储/邮件/安装密钥/Connect 令牌/集成开关逐项详解,connect.config.json 与证书四形态,约 20 个 CLEARFLASK_* 环境变量注入优先级,改配生效流程与实测排障(令牌不一致 401、门户 403 强跳 HTTPS 等)。
ClearFlask 2.7.2 配置参数详解
目标:把 ClearFlask 2.7.2 self-host 的配置体系讲透——全局配置文件
server/config-selfhost.cfg的语法与每一项参数、Node 侧connect.config.json、约 20 个CLEARFLASK_*环境变量的注入与优先级、首次启动自动生成的安装密钥,以及改完如何生效与验证。全文以 2026-11-01 本地实测环境为例证,关键值均来自真实配置文件与命令回显。
一、环境信息
| 项目 | 值 |
|---|---|
| 组件版本 | ClearFlask 2.7.2 |
| 全局配置文件 | /opt/clearflask/server/config-selfhost.cfg(实测 186 行 / 11889 字节) |
| Node 侧配置文件 | /opt/clearflask/connect/connect.config.json |
| 服务形态 | Java 服务(Tomcat 9.0.123 / JVM 17.0.20.1)+ Node 前端服务,进程由部署编排管理 |
| 对外入口 | http://127.0.0.1:8130(Node 服务监听 9080,Java 服务 8080 仅内部) |
| 生效方式 | 修改 cfg 后重启 Java 服务进程;环境变量在进程启动时注入 |
⚠️ 宿主前置:本文的重启/进程核查命令按真机(systemd 或等价进程管理)形态书写。本系列实测环境的两套服务由编排文件拉起(见 《ClearFlask 2.7.2 Docker Compose 部署指南》),真机部署需自备对应 unit 或以你实际的进程管理方式等价执行。
二、配置体系总览
ClearFlask 的配置分三层:
| 层 | 载体 | 管什么 | 何时生效 |
|---|---|---|---|
| 全局层 | server/config-selfhost.cfg | 域名、注册白名单、数据源、邮件、存储、密钥、集成开关 | Java 服务启动时读取,改后需重启 |
| 注入层 | CLEARFLASK_* 环境变量 | 覆盖全局层同名项(适配无法编辑持久文件的平台) | 进程启动时强制覆盖文件值 |
| 项目层 | 数据库内的项目 Config(仪表盘/API 维护) | 每个反馈板的分类、工作流、品牌、用户引导 | 保存即生效,无需重启 |
本文聚焦前两层;项目层 Config 的完整读写实操见 《ClearFlask 2.7.2 常用 CLI 命令与 API 详解》。
2.1 cfg 文件语法
config-selfhost.cfg 是 Java 配置框架(kik ConfigSystem)的属性文件,每行一个参数,键为实现类全限定名 + $Config. + 属性名:
# 井号行为注释;键=值,也支持键:值写法
com.smotana.clearflask.web.Application$Config.domain=localhost
com.smotana.clearflask.web.Application$Config.defaultSearchEngine:READWRITE_MYSQL
被注释掉的行(行首 #)表示"采用代码内默认值"——官方模板把不常用项全部注释好放在文件里,取消注释即启用,这是阅读该文件最重要的心智模型。
三、域名与访问控制组
参数(省略 com.smotana.clearflask. 前缀) | 实测值 | 说明 |
|---|---|---|
web.Application$Config.domain | localhost | 全局主域名。生产改为 feedback.example.com 形式;不支持子路径部署(不能挂 example.com/clearflask/) |
web.security.SuperAdminPredicate$Config.superAdminEmailRegex | ^admin@localhost$ | 超管注册邮箱白名单正则,仅匹配者能在仪表盘注册账号 |
web.resource.AccountResource$Config.signupEnabled | true | 仪表盘注册总开关。官方建议注册完成后立即改 false;实测重复注册已存在邮箱返回 409 {"userFacingMessage":"Email already in use"} |
web.security.AuthCookieImpl$Config.authCookieSecure | false | 认证 Cookie 是否加 Secure 位。上 HTTPS 后必须改 true,否则浏览器不回传 Cookie(表现为"登录成功但立刻掉线") |
web.Application$Config.enableTelemetry | false | 遥测开关,本实测环境已关 |
💡 环境变量等价项:
CLEARFLASK_DOMAIN、CLEARFLASK_SUPER_ADMIN_EMAIL、CLEARFLASK_SIGNUP_ENABLED、CLEARFLASK_AUTH_COOKIE_SECURE、CLEARFLASK_TELEMETRY_ENABLED。另有CLEARFLASK_TRUSTED_PROXY_COUNT(默认 1,即 Node 前端服务这一层;前面再加一层负载均衡则设 2)——限流按该位置取客户端 IP,设错会让限流打在代理 IP 上。
四、数据源与搜索引擎组
ClearFlask 的源数据在 DynamoDB 兼容存储,MySQL/ElasticSearch 只是可热切换的搜索索引(实测 MySQL 库 clearflask 仅 7 张索引表:account / comment / comment_parent_id / idea / idea_funders / idea_tags / user,账号等业务数据实际在 DynamoDB 单表 clearflaskprimary 中——排障时别在 MySQL 里找业务数据)。
| 参数 | 实测值 | 说明 |
|---|---|---|
store.dynamo.DefaultDynamoDbProvider$Config.serviceEndpoint | http://localstack:4566 | DynamoDB 端点。用真实 AWS 时注释掉本行及 signingRegion |
...DefaultDynamoDbProvider$Config.signingRegion / productionRegion | us-east-1 | 签名区/生产区 |
store.mysql.DefaultMysqlProvider$Config.host / user / pass | mysql-db / root / clearflask | 搜索索引库连接;root 密码为内置众所周知值,依赖"数据库端口不对外"保安全 |
store.elastic.DefaultElasticSearchProvider$Config.serviceEndpoint | http://elasticsearch:9200(注释态) | 选 ES 引擎时启用 |
web.Application$Config.defaultSearchEngine | READWRITE_MYSQL | 索引引擎,见下表 |
web.Application$Config.startupWaitUntilDeps | true | 启动时轮询等待依赖就绪(与依赖同机编排时避免竞态) |
web.Application$Config.createIndexesOnStartup | true | 启动时自动建索引表/映射 |
defaultSearchEngine 取值(迁移中间态用于双写灰度):
| 值 | 读 | 写 |
|---|---|---|
READWRITE_MYSQL | MySQL | MySQL |
READWRITE_ELASTICSEARCH | ES | ES |
READ_MYSQL_WRITE_BOTH | MySQL | 双写 |
READ_ELASTICSEARCH_WRITE_BOTH | ES | 双写 |
💡 官方默认值是 ElasticSearch——cfg 里找不到这一行时按 ES 运行。MySQL 与 ES 间在线迁移走 JMX 调用
ProjectResource.createIndexes/reindexProjects配合双写四步切换,完整流程见官方 README "Migration between Elasticsearch/MySQL" 节;小项目用 MySQL(前缀匹配),大项目用 ES(词形归并,搜 "Johnny" 命中 "Jonathan")。
五、对象存储组(附件/S3)
| 参数 | 实测值 | 说明 |
|---|---|---|
store.s3.DefaultS3ClientProvider$Config.serviceEndpoint | http://s3.localhost.localstack.cloud:4566 | S3 兼容端点;真实 S3 时注释本行及 signingRegion/proxyEnabled/proxyResolveTo |
...DefaultS3ClientProvider$Config.signingRegion / productionRegion | us-east-1 | 同上 |
...DefaultS3ClientProvider$Config.dnsResolverTo | localstack | 把虚拟主机名解析到存储服务主机 |
store.impl.S3ContentStore$Config.hostname | local-upload.s3.localhost.localstack.cloud:4566 | 生成附件 URL 的 host;真实 S3 填 <bucket>.s3.amazonaws.com |
...S3ContentStore$Config.bucketName | local-upload | 桶名,实测 s3 ls 可见该桶已自动创建 |
...S3ContentStore$Config.scheme | http | 生产 https 站点改 https |
...S3ContentStore$Config.createBucket | true | 启动时自动建桶 |
...S3ContentStore$Config.proxyEnabled / proxyResolveTo | true / localstack | 预签名 URL 代理。真实 S3 设 false,localstack 设 true(官方注释原话) |
六、邮件组
| 参数 | 实测值 | 说明 |
|---|---|---|
core.push.provider.EmailServiceImpl$Config.useService | ses | ses 或 smtp 二选一 |
core.email.AmazonSimpleEmailServiceProvider$Config.region | us-east-1 | SES 区域 |
...AmazonSimpleEmailServiceProvider$Config.serviceEndpoint | http://localstack:4566 | 指向 localstack 时邮件实际不发(官方默认即如此,"which doesn't do anything") |
SMTP 形态需填的 8 项(官方 Gmail 示例):
EmailServiceImpl$Config.smtpStrategy=SMTP_TLS # SMTP_TLS(587) / SMTPS(465) / SMTP(25)
EmailServiceImpl$Config.smtpHost=smtp.gmail.com
EmailServiceImpl$Config.smtpPort=587
EmailServiceImpl$Config.smtpUser=my.name@gmail.com
EmailServiceImpl$Config.smtpPassword=<应用专用密码> # 开了 2FA 必须用 app password
EmailServiceImpl$Config.emailDisplayName=ClearFlask for MyCompany
EmailServiceImpl$Config.fromEmailLocalPart=my.name
EmailServiceImpl$Config.fromEmailDomainOverride=gmail.com
环境变量捷径:设 CLEARFLASK_SMTP_HOST 即自动把 useService 切到 SMTP,配合 CLEARFLASK_SMTP_PORT/USER/PASSWORD/STRATEGY 与 CLEARFLASK_EMAIL_DISPLAY_NAME/FROM_LOCAL_PART/FROM_DOMAIN。
七、安装密钥组(首启自动生成)
首次启动时以下 5 组密钥自动生成并写入 cfg(本实测值示意,部署时务必以你机器上的新值为准,切勿复用):
| 参数 | 用途 | 手工再生成命令(官方注释) |
|---|---|---|
core.push.provider.BrowserPushServiceImpl$Config.publicKey / privateKey | 浏览器推送 VAPID 公私钥 | npx web-push generate-vapid-keys |
util.DefaultServerSecret$Config.sharedKey:cursor | 搜索游标加密 | openssl rand -base64 16 |
store.impl.DynamoElasticUserStore$Config.tokenSignerPrivKey | 魔法登录邮件 JWT 签名私钥 | openssl rand -base64 172 | tr -d '\n' |
security.ClearFlaskSso$Config.secretKey | SSO 单点登录密钥 | uuidgen |
web.resource.GitLabResource$Config.webhookSecret / JiraResource$Config.webhookSecret | GitLab/Jira 集成派生 webhook token 的服务端母密钥(从不直接外发) | openssl rand -hex 32 |
⚠️ 官方 README 安全提示:此行为之前的老安装共享公开已知的默认密钥——启动日志出现
SECURITY:警告必须按注释命令重新生成。cfg 文件含全部密钥,权限收紧(chmod 600),备份视同备份数据库。
八、Connect 协同与证书形态组
Java 与 Node 两套服务用共享令牌互信:
| 参数 | 实测值 | 说明 |
|---|---|---|
web.security.AuthenticationFilter$Config.connectToken | 2b2677bb5b9b4c98866c3daacd90c746 | Node 侧转发到 Java 侧的鉴权令牌;Node 侧同名配置在 connect.config.json |
connect.config.json 实测关键字段:
{
"connectToken": "7cb1e1c26f5d4705a213529257d081c6",
"parentDomain": "localhost",
"apiBasePath": "http://<java服务主机>:8080",
"disableAutoFetchCertificate": true,
"forceRedirectHttpToHttps": false
}
parentDomain:项目门户按<slug>.<parentDomain>寻址(slug=demo →demo.localhost)。apiBasePath:Node 转发 API 请求的 Java 侧地址。- 证书三开关组合(官方四形态):
| 形态 | disableAutoFetchCertificate | forceRedirectHttpToHttps | authCookieSecure | 备注 |
|---|---|---|---|---|
| Let's Encrypt 自动 | false | true | true | 首次访问自动签发/续期 |
| 自有静态证书 | false | true | true | 另配 security.CertFetcherImpl$Config.staticCert(单行 JSON,含 cert/chain/keypair) |
| 反向代理自管 TLS | true | true | true | 代理终结 TLS,仍要求 https 跳转 |
| 纯 HTTP(本实测) | true | false | false | 官方不推荐;Node 侧仅监听 9080,无 HTTPS 监听 |
💡 实测优先级证据:本环境
connect.config.json里的令牌是初始值7cb1e1c2…,与.env/cfg 的2b2677bb…不一致,但全链路 API 实测以2b2677bb…为准并成功——环境变量注入优先于文件值(README 原话 "always take precedence over values in the file")。三处令牌以CLEARFLASK_CONNECT_TOKEN环境变量为唯一事实源最省心;不一致的典型症状是 Java 侧对 Node 转发的请求回 401。
九、可选集成组
| 集成 | 参数组 | 启用要点(README 实测口径) |
|---|---|---|
| Google ReCaptcha | security.limiter.challenge.CaptchaChallenger$Config.enabled/siteKey/secretKey | 本实测 enabled=false;开启后注册/限流走人机质询 |
| GitHub App(issue 双向同步) | store.github.GitHubStoreImpl$Config.enabled=false + appId/privateKeyPem/clientSecret + GitHubResource$Config.webhookSecret | 私钥需 PKCS8 化并压成单行:openssl pkcs8 -topk8 -inform PEM -outform PEM -in private-key.pem -out private-key.pem.pkcs8 -nocrypt 后 awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}';webhook 回调 https://<域名>/api/v1/webhook/github |
| GitLab / Jira / Slack OAuth | 各 ...StoreImpl$Config.clientId/clientSecret(注释模板) | 回调 URL 统一设 https://<域名>/dashboard;client id 同时要加进 connect.config.json;GitLab 需 api+read_user 且 Confidential=Yes |
| AI 反馈摘要(LangChain) | store.impl.LangChainLlmAgentStore$Config.openAiApiKey/openAiModelName/openAiBaseUrl/temperature + DynamoLlmMemoryStore$Config.memoryMaxTokens | 仅 OpenAI 完整支持,默认模型 GPT_4_O_MINI |
| AWS 凭据 | store.ConfigAwsCredentialsProvider$Config.awsAccessKeyId/awsSecretKey(实测 test/test) | 也可留空注释,走标准凭据链:环境变量 AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY、Java 系统属性、~/.aws/credentials、EC2/ECS 实例角色、Web Identity Token |
十、环境变量注入全表(Java 服务侧)
官方支持约 20 个 CLEARFLASK_* 变量在启动时注入并强制覆盖 cfg 文件值(适配 Railway/PikaPods/Elestio 等无法编辑持久文件的平台):
| 变量 | 覆盖项 |
|---|---|
CLEARFLASK_DOMAIN | 主域名 |
CLEARFLASK_SUPER_ADMIN_EMAIL | 超管注册白名单 |
CLEARFLASK_SIGNUP_ENABLED | 注册开关 |
CLEARFLASK_AUTH_COOKIE_SECURE | 安全 Cookie |
CLEARFLASK_TRUSTED_PROXY_COUNT | 前置可信代理数 |
CLEARFLASK_CONNECT_TOKEN | 两套服务共享令牌(两侧都要设同值) |
CLEARFLASK_TELEMETRY_ENABLED | 遥测 |
CLEARFLASK_OUTBOUND_ALLOW_PRIVATE_ADDRESSES | 允许 OAuth/webhook 指向内网地址(默认 false,防 SSRF) |
CLEARFLASK_OUTBOUND_ALLOW_PLAIN_HTTP | 允许 http:// 的 OAuth/webhook URL(默认 false) |
CLEARFLASK_SMTP_HOST/PORT/USER/PASSWORD/STRATEGY | SMTP 五件套(设 host 即切 SMTP) |
CLEARFLASK_EMAIL_DISPLAY_NAME/FROM_LOCAL_PART/FROM_DOMAIN | 发件人身份 |
CLEARFLASK_MYSQL_HOST/USER/PASSWORD | 索引库连接 |
CLEARFLASK_DYNAMO_ENDPOINT/ES_ENDPOINT/S3_ENDPOINT | 三类依赖端点 |
CLEARFLASK_EXTRA_PROPS | 兜底:换行分隔的任意 全键=值 行 |
Node 服务侧支持:CLEARFLASK_CONNECT_TOKEN、CLEARFLASK_DOMAIN、CLEARFLASK_API_BASE_PATH、CLEARFLASK_LISTEN_PORT、CLEARFLASK_DISABLE_AUTO_FETCH_CERTIFICATE、CLEARFLASK_FORCE_REDIRECT_HTTPS(覆盖 connect.config.json)。另有 CLEARFLASK_CREATE_SERVER_CONFIG_IF_MISSING / CLEARFLASK_CREATE_CONNECT_CONFIG_IF_MISSING 控制首启是否自动生成配置文件。
十一、修改与生效流程(实测)
- 改配置(示例:关闭注册):
vi /opt/clearflask/server/config-selfhost.cfg
# signupEnabled=true → false
- 重启 Java 服务进程使其生效(真机形态):
systemctl restart clearflask-server
⚠️ 本系列实测环境以部署编排的等价重启操作执行;真机需自备 unit 文件(ExecStart 指向 Java 服务启动命令,Environment 注入
CLEARFLASK_*)。
- 验证生效(服务器视角,实测回显):
$ ps -ef | grep 'catalina.base' | grep -v grep | head -1
root 792229 792202 15 19:32 ? 00:05:32 /opt/java/openjdk/bin/java ... -Xms256m -Xmx512m ... org.apache.catalina.startup.Bootstrap start
$ curl -s http://127.0.0.1:8130/api/health
ok
$ ss -ltn | grep ':8130\b'
LISTEN 0 4096 0.0.0.0:8130 0.0.0.0:*
十二、实测排障记录
| 症状 | 根因(配置项) | 处置 |
|---|---|---|
| Java 侧对 API 请求回 401 | connectToken 三处不一致(env/cfg/connect.config.json) | 以 CLEARFLASK_CONNECT_TOKEN 为唯一事实源,改齐重启 |
门户子域 POST 回 403 且 Location: https://... | 纯 HTTP 形态下 Node 侧仍对门户域写操作强跳 HTTPS | 按第八节选证书形态;纯本地验证走 Java 内网 API(见 D1) |
| 注册被拒/403 | superAdminEmailRegex 不匹配或 signupEnabled=false | 核对第三节两项 |
| 登录成功立刻掉线 | 上了 HTTPS 但 authCookieSecure=false(或反之) | 与协议形态保持一致 |
cfg 没写 defaultSearchEngine 却连不上 ES | 缺省即 ElasticSearch | 显式写 READWRITE_MYSQL |
老升级实例启动日志 SECURITY: 警告 | 共享公开默认密钥 | 按第七节命令全部再生成 |
十三、相关文章与参考
- 《ClearFlask 2.7.2 介绍与选型指南》
- 《ClearFlask 2.7.2 Docker Compose 部署指南》
- 《ClearFlask 2.7.2 常用 CLI 命令与 API 详解》
- 官方 README(配置/环境变量/证书/迁移权威来源):https://github.com/clearflask/clearflask
- Helm values 形态的配置对照(K8s 部署):https://github.com/clearflask/clearflask/blob/master/clearflask-helm/README.md