Fusio 7.2.1 配置参数详解
讲清 Fusio 7.2.1 的配置体系——FUSIO_* 环境变量、.env 与 configuration.php 三个入口的加载顺序与优先级,逐项解析全部配置键的默认取值与实际行为,并对令牌有效期、防火墙、用户注册等关键参数给出真实环境实测结论,全程基于 7.2.1 实机验证。
Fusio 7.2.1 配置参数详解
目标:讲清 Fusio 7.2.1 的配置体系——FUSIO_* 环境变量、.env 与 configuration.php 三个入口的加载顺序与优先级,逐项解析全部配置键的默认取值与实际行为,并对令牌有效期、防火墙、用户注册等关键参数给出真实环境实测结论,全程基于 7.2.1 实机验证。
一、本文环境与实测口径
本文所有配置键取值与实验结论均在 《Fusio 7.2.1 Docker Compose 部署指南》 部署的同构环境上实测取得(实测日期 2026-10-24),环境基线如下:
| 项目 | 实测值 |
|---|---|
| Fusio 版本 | 7.2.1(fusio/fusio:7.2.1,API 版本号 v8.9.3) |
| 数据库 | MySQL 9(mysql:9,实测 9.7.4) |
| 访问方式 | 宿主机 8148 端口 → 应用 80 端口 |
| 平台对外地址(FUSIO_URL) | http://192.168.1.62:8148 |
| 管理员账号 | admin / q1w2e3r4(演示口令) |
| 应用安装目录 | /var/www/html/fusio(官方镜像固定路径) |
| 配置文件 | /var/www/html/fusio/configuration.php |
写作口径约定:涉及文件修改与命令执行的操作,均在部署目录下通过 docker compose exec fusio <命令> 完成(Compose 部署的标准运维入口);若你按 《Fusio 7.2.1 Docker Compose 部署指南》 部署,命令可直接照抄。文章只讨论配置本身,不再重复部署步骤。
二、配置体系总览:三个入口与优先级
2.1 三个配置入口
Fusio 7.2.1 的配置有三条进入系统的通道,先建立全局认知再逐项展开:
| 入口 | 位置 | 作用 | 本文结论 |
|---|---|---|---|
FUSIO_* 环境变量 | Compose environment(或 docker run -e) | 主配置通道:configuration.php 用 env('FUSIO_XXX') 读取;另有少数变量由启动脚本直接消费 | 推荐通道,改 Compose 重启即生效 |
configuration.php | /var/www/html/fusio/configuration.php | 全量配置键的唯一定义处,约 40 个键,含默认值与 env 映射 | 高级配置,改动后必须清缓存 |
.env | /var/www/html/fusio/.env | 镜像自带文件,键为 APP_* 前缀 | Docker 部署下不参与配置(见 2.2) |
2.2 加载顺序与优先级(源码结论)
配置加载发生在框架容器编译阶段,vendor/psx/framework/src/Dependency/ContainerBuilder.php 的 build() 方法(实机转录):
public static function build(string $appDir, ?bool $debug, ...$containerFiles): ContainerInterface
{
$dotenv = new Dotenv();
$dotenv->load($appDir . '/.env');
if ($debug === null) {
$debug = ($_ENV['APP_DEBUG'] ?? '') === 'true';
}
$targetFile = $appDir . '/cache/container.php';
$containerConfigCache = new ConfigCache($targetFile, $debug);
if (!$containerConfigCache->isFresh()) {
$containerBuilder = self::getContainerBuilder($appDir, $containerFiles);
$containerBuilder->compile();
$dumper = new PhpDumper($containerBuilder);
$containerConfigCache->write($dumper->dump(), $containerBuilder->getResources());
}
require_once $targetFile;
// ...
}
由此得到两条关键结论:
- 真实环境变量优先于 .env:Symfony Dotenv 的
load()语义是"不覆盖已存在的环境变量",.env只补缺。因此 Compose 里设置的FUSIO_*永远赢过.env。 - Docker 部署下 .env 实际不参与配置:镜像自带
.env的键是APP_*前缀(APP_PROJECT_KEY、APP_DEBUG、APP_CONNECTION等,实测文件内容转录如下),而 configuration.php 只读FUSIO_*,两套名字对不上。实机.env内容:
APP_PROJECT_KEY="cee262a5a1bdd205cbfe0dfc2ad4eddf"
# dev or prod
APP_ENV=dev
# true or false
APP_DEBUG=true
APP_CONNECTION="pdo-mysql://root:test1234@localhost/fusio"
APP_MAILER="native://default"
APP_MESSENGER="doctrine://default"
APP_URL=""
APP_APPS_URL=""
APP_MAIL_SENDER=""
APP_TRUSTED_IP_HEADER=""
APP_TENANT_ID=""
SDKGEN_CLIENT_ID=""
SDKGEN_CLIENT_SECRET=""
⚠️ 别被这份
.env里的APP_DEBUG=true迷惑——它对 Docker 部署没有任何效果,生产行为由 Compose 里的FUSIO_DEBUG决定。
2.3 配置的编译与缓存(改配置不生效的头号原因)
从上面的源码还能看到:配置并不是每次请求都重新读取,而是编译成 cache/container.php 缓存文件(本环境实测该文件 979260 字节、属主 www-data、首次请求时自动重编译)。关键规则:
psx_debug=false(生产形态)时,Symfony ConfigCache 不会自动检测 configuration.php 的变化;- 因此改完 configuration.php 必须手动删缓存才能生效:
rm -f /var/www/html/fusio/cache/container.php
- 删除后的下一次请求会自动重编译,实测重编译产物同样为 979260 字节左右、属主自动回落为 www-data,无需手工干预。
这一机制在第五节令牌有效期实验中有直接证据。
三、FUSIO_* 环境变量逐项说明
3.1 configuration.php 消费的变量(映射表)
下表是"环境变量 → configuration.php 配置键"的完整映射(从 configuration.php 逐行核对):
| 环境变量 | configuration.php 键 | 本环境实测值 |
|---|---|---|
FUSIO_TENANT_ID | fusio_tenant_id | 空(单租户) |
FUSIO_PROJECT_KEY | fusio_project_key | 42eec18ffdbffc9fda6110dcc705d6ce |
FUSIO_MAIL_SENDER | fusio_mail_sender | 空 |
FUSIO_APPS_URL | fusio_apps_url | 空 |
FUSIO_URL | psx_url | http://192.168.1.62:8148 |
FUSIO_ENV | psx_env | prod |
FUSIO_DEBUG | psx_debug | false |
FUSIO_CONNECTION | psx_connection | pdo-mysql://fusio:q1w2e3r4@mysql-fusio/fusio |
FUSIO_MAILER | psx_mailer | native://default |
FUSIO_MESSENGER | psx_messenger | doctrine://default |
FUSIO_TRUSTED_IP_HEADER | psx_trusted_ip_header | 空 |
SDKGEN_CLIENT_ID | sdkgen_client_id | 空 |
SDKGEN_CLIENT_SECRET | sdkgen_client_secret | 空 |
3.2 启动脚本直接消费的变量
以下变量不进 configuration.php,而是由镜像入口脚本 docker-entrypoint.sh 在每次启动时消费(实机转录关键段):
# wait for external services
php bin/fusio system:wait_for
# install fusio
php bin/fusio migration:up-to-date
if [ $? -ne 0 ]; then
php bin/fusio migration:migrate --no-interaction
fi
# add initial backend user
php bin/fusio system:check user
if [ $? -ne 0 ]; then
php bin/fusio adduser --role=1 --username="$FUSIO_BACKEND_USER" \
--email="$FUSIO_BACKEND_EMAIL" --password="$FUSIO_BACKEND_PW"
fi
| 变量 | 消费点 | 行为 |
|---|---|---|
FUSIO_BACKEND_USER / _EMAIL / _PW | 启动时 system:check user 检查失败则执行 adduser --role=1 | 仅首次初始化建管理员,已存在则跳过(改这三个变量不会重置已有管理员密码) |
FUSIO_WORKER_JAVA / _JAVASCRIPT / _PHP / _PYTHON | 非空时生成连接 JSON 并 connection:create(已存在则 update) | 自动注册对应语言 Worker 连接,类型 Fusio.Adapter.Worker.Connection.Worker,地址如 http://worker-php:9092 |
3.3 本环境实测变量全集
对运行中实例实查的环境变量全集(docker inspect 转录,按字母序),可与你的 Compose 逐项对照:
FUSIO_APPS_URL=
FUSIO_BACKEND_EMAIL=admin@example.com
FUSIO_BACKEND_PW=q1w2e3r4
FUSIO_BACKEND_USER=admin
FUSIO_CONNECTION=pdo-mysql://fusio:q1w2e3r4@mysql-fusio/fusio
FUSIO_DEBUG=false
FUSIO_ENV=prod
FUSIO_MAILER=native://default
FUSIO_MAIL_SENDER=
FUSIO_MARKETPLACE=off
FUSIO_MESSENGER=doctrine://default
FUSIO_PROJECT_KEY=42eec18ffdbffc9fda6110dcc705d6ce
FUSIO_TENANT_ID=
FUSIO_TRUSTED_IP_HEADER=
FUSIO_URL=http://192.168.1.62:8148
FUSIO_WORKER_JAVA=
FUSIO_WORKER_JAVASCRIPT=
FUSIO_WORKER_PHP=
FUSIO_WORKER_PYTHON=
关于 FUSIO_MARKETPLACE:上述列表里出现了它(值 off),但实测在入口脚本、平台源码中检索均无消费点(0 命中),configuration.php 也没有对应键。结论:这是镜像预留的无效变量,设不设、设什么值都不影响行为,不必效仿。
3.4 环境变量的传递:env.sh 与 cron
入口脚本启动收尾时会生成一份 env.sh,把当前全部 FUSIO_* 变量导出(实机内容节选):
#!/bin/bash
export FUSIO_APPS_URL=""
export FUSIO_BACKEND_EMAIL="admin@example.com"
export FUSIO_BACKEND_PW="q1w2e3r4"
export FUSIO_BACKEND_USER="admin"
export FUSIO_CONNECTION="pdo-mysql://fusio:q1w2e3r4@mysql-fusio/fusio"
export FUSIO_DEBUG="false"
export FUSIO_ENV="prod"
...
export FUSIO_URL="http://192.168.1.62:8148"
它的用途是让非入口脚本的子进程(定时任务等)也能继承同一套配置。镜像内置三条 cron 计划任务(/etc/cron.d 实查):
* * * * * www-data /var/www/html/fusio/run_cron.sh cronjob
0 0 1 * * www-data /var/www/html/fusio/run_cron.sh log_rotate
0 0 1 * * www-data /var/www/html/fusio/run_cron.sh clean
分别对应:每分钟检查执行计划任务、每月 1 日轮转日志表、每月 1 日清理过期数据——与 《Fusio 7.2.1 常用 CLI 命令与 API 实测详解》 中的 system:cronjob_execute、system:log_rotate、system:clean 三条命令一一对应。
四、configuration.php 全量参数详解
以下按 configuration.php 的分组顺序逐键解析。默认值一列即本环境实查值(未做任何改动的基础状态);没有对应环境变量的键为源码硬编码。
4.1 防火墙组(fusio_firewall_*)
| 键 | 默认值 | 说明 |
|---|---|---|
fusio_firewall_ignoreip | [] | 防火墙白名单 IP 数组,命中的 IP 不参与错误计数与封禁;反代场景可把网关地址加入 |
fusio_firewall_bantime | 'PT5M' | 封禁时长,ISO 8601 duration 格式(PT5M = 5 分钟,PT30S = 30 秒,P1D = 1 天) |
fusio_firewall_findtime | 'PT2M' | 错误计数统计窗口(PT2M = 2 分钟),窗口内该 IP 的客户端错误次数达到阈值即封禁 |
fusio_firewall_maxretry | 32 | 阈值。注意是严格大于才触发(源码 $count > maxretry),即默认第 33 次错误才封禁 |
fusio_firewall_codes | [] | 计入统计的响应码白名单;空数组 = 全部客户端错误都计数;配置后仅列表内响应码计数 |
防火墙的完整机制与实测(含阈值边界、封禁期表现、误封网关 IP 的真实案例)见第六节。
4.2 MCP / JsonRPC / GraphQL 组(实验性协议端点)
| 键 | 默认值 | 说明 |
|---|---|---|
fusio_mcp | false | 是否启用 HTTP 端点 /mcp(Model Context Protocol)。关闭时访问该端点返回 MCP service is not enabled;CLI 方式(php bin/fusio system:mcp)不受此开关限制,始终可用 |
fusio_mcp_queue_size | 500 | MCP 服务队列大小 |
fusio_mcp_timeout | 1800 | MCP 超时(秒),1800 = 30 分钟 |
fusio_jsonrpc | false | 是否启用 /jsonrpc 端点,允许通过 JsonRPC 调用任意操作;官方建议对外仍用 REST |
fusio_graphql | false | 是否启用 /graphql 端点,允许以 GraphQL 查询 GET 操作。关闭时返回 GraphQL service is not enabled(实测回显) |
三个端点默认全关是安全默认值;本环境对 /graphql 与 /mcp 的关闭态响应均实测过,打开方式即改键后清缓存。
4.3 OAuth2 令牌有效期组
| 键 | 默认值 | 说明 |
|---|---|---|
fusio_expire_token | 'P2D' | 访问令牌(access token)有效期,ISO 8601 duration。P2D = 2 天,对应签发响应 expires_in: 172800 |
fusio_expire_refresh | 'P3D' | 刷新令牌有效期,P3D = 3 天。过期后只能重新认证 |
实测要点:这一组是本文验证最充分的参数——改 fusio_expire_token 后不清缓存不生效、清缓存立即生效,四步实验与签发回显见第五节。
4.4 实例标识与加密
| 键 | 默认值 | 说明 |
|---|---|---|
fusio_tenant_id | env FUSIO_TENANT_ID(空) | 多租户隔离标识;所有库表按 tenant 分隔。单实例自用保持为空 |
fusio_project_key | env FUSIO_PROJECT_KEY | 项目密钥,用于加密数据库中保存的连接凭据(如 MySQL 连接的密码)。官方注释明确警告:安装后更换此键将导致既有加密数据不可读,只在首次安装前设置 |
fusio_action_exclude | null | 禁用的 Action 类数组(黑名单),如某些不安全的内置 Action |
fusio_connection_exclude | null | 禁用的连接类型类数组(黑名单) |
fusio_provider | __DIR__ . '/provider.php' | Provider 清单文件,注册系统能力的适配器类。7.2.1 默认 provider.php 注册 20 个适配器:Ai/Amqp/Beanstalk/Cli/Elasticsearch/Fcgi/File/GraphQL/Http/Memcache/Mongodb/Php/Redis/SdkFabric/Smtp/Soap/Sql/Stripe/Util/Worker |
psx_trusted_ip_header | env FUSIO_TRUSTED_IP_HEADER(空) | 反向代理场景取真实客户端 IP 的请求头(如 X-Forwarded-For)。不配则防火墙把代理 IP 当客户端 IP,可能误封全网用户(真实案例见 6.5) |
4.5 功能开关组
| 键 | 默认值 | 说明 |
|---|---|---|
fusio_registration | true | 是否开放自注册。false 时 POST /consumer/register 返回 503 User registration is not enabled(实测回显见第七节)。私有部署建议关闭,改用管理员建号 |
fusio_connection | true | 是否启用连接端点(允许通过后端接口访问/修改数据库或文件系统)。暴露面大的环境可关 |
fusio_marketplace | true | 是否启用应用市场(后台可下载安装应用) |
fusio_apps_url | env FUSIO_APPS_URL(空) | 应用门户对外地址(如 http://acme.com/apps),默认跟随主 URL |
fusio_apps_dir | __DIR__ . '/public/apps' | 市场应用的落盘目录(默认 public 下可直接访问) |
4.6 邮件与队列组
| 键 | 默认值 | 说明 |
|---|---|---|
fusio_mail_sender | env FUSIO_MAIL_SENDER(空) | 系统邮件发件人地址 |
psx_mailer | env FUSIO_MAILER(native://default) | Symfony Mailer DSN。生产建议改 smtp://用户:密码@smtp.example.com:587;验证命令 system:mail_test 见 《Fusio 7.2.1 常用 CLI 命令与 API 实测详解》 |
psx_messenger | env FUSIO_MESSENGER(doctrine://default) | 异步消息队列传输 DSN,默认走数据库表(无需额外中间件);常驻消费由 supervisor 托管(messenger:consume --time-limit=3600,实查配置) |
4.7 PSX 框架组(路径、日志与其他)
| 键 | 默认值 | 说明 |
|---|---|---|
psx_url | env FUSIO_URL | 平台对外地址,生成的 OpenAPI/TypeAPI 规范与链接都以它为准 |
psx_dispatch | '' | 路径分发前缀;Apache 直接托管时保持空串 |
psx_env | env FUSIO_ENV(prod) | 运行环境(prod/dev) |
psx_debug | env FUSIO_DEBUG(false) | 调试开关。false 时错误显示关闭且启用配置编译缓存(第二节机制);true 时缓存每次重新编译,便于开发 |
psx_connection | env FUSIO_CONNECTION | Doctrine DBAL 元数据库连接串,pdo- 前缀区分驱动(pdo-mysql/pdo-pgsql 等) |
psx_migration_namespace | 'App\Migrations' | 迁移类命名空间(自建迁移时用到) |
psx_log_level | Logger::ERROR | 日志级别(Monolog 常量) |
psx_path_cache | __DIR__ . '/cache' | 缓存目录(container.php 所在地) |
psx_path_log | 'php://error_log' | 日志输出目标(默认交给 PHP error_log,即 Apache 错误日志) |
psx_path_public / psx_path_resources / psx_path_src | __DIR__ 下对应子目录 | 公开目录 / 资源目录 / 源码目录 |
psx_supported_writer | Json/Jsonp/Jsonx 三个类 | 支持的响应序列化器,一般不动 |
sdkgen_client_id / sdkgen_client_secret | env(空) | SDKgen 平台凭证,用于 SDK 生成器扩展,自托管可留空 |
五、实测一:令牌有效期与配置缓存
这是最能说明"改配置必须清缓存"的一组实验。实验对象 fusio_expire_token,验证手段是重复请求 OAuth2 令牌端点,观察签发响应中的 expires_in(单位秒)。实验在部署环境的应用目录执行,请求通过宿主 8148 端口发起:
curl -s -X POST http://127.0.0.1:8148/authorization/token \
-u "c5c26de3-7d0a-4c6b-bccb-bc5c2d7e3b16:<app_secret>" \
-d "grant_type=client_credentials&scope=authorization"
说明:
-u的客户端凭证来自后台应用fusio的 app_key/app_secret(可在数据库fusio_app表或后台应用管理页查到,app_key 实测为c5c26de3-7d0a-4c6b-bccb-bc5c2d7e3b16)。
四步实验与结果:
| 步骤 | 操作 | 签发响应 expires_in | 结论 |
|---|---|---|---|
| 1 | 配置保持默认 P2D,删除缓存后请求 | 172800(= 2 天) | 基线成立 |
| 2 | 改 configuration.php 为 'PT1H',不清缓存直接请求 | 172800(旧值) | 缓存未失效,改动不生效 |
| 3 | rm -f cache/container.php 后再请求 | 3600(= 1 小时) | 清缓存后立即生效 |
| 4 | 恢复 P2D + 清缓存 | 172800 | 恢复确认 |
步骤 3 的完整签发回显(实测 JSON):
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTkyLjE2OC4xLjYyOjgxNDgiLCJzdWIiOiI0NTVmYjQ5Yi0xOGQ5LTVkNGMtOTMzYi1iZWNjYTNhNzQ3MDgiLCJpYXQiOjE3OTI4MDMwMzAsImV4cCI6MTc5MjgwNjYzMCwibmFtZSI6ImFkbWluIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJhdWQiOiJjNWMyNmRlMy03ZDBhLTRjNmItYmNjYi1iYzVjMmQ3ZTNiMTYiLCJlbWFpbCI6ImFkbWluQGV4YW1wbGUuY29tIn0.I7je9SottRiXSjueryo_gxNO3qmmk7Ui9NAhx6_WZTM",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "ede274a03a10466ffb5f-e14f90ae8e8534596f059447d7b699121c8079642a1fec16-dbdb15123a",
"scope": "authorization"
}
把该 access_token 的 JWT 中段做 Base64 解码,声明与配置完全对应:
{
"iss": "http://192.168.1.62:8148",
"sub": "455fb49b-18d9-5d4c-933b-becca3a74708",
"iat": 1792803030,
"exp": 1792806630,
"name": "admin",
"preferred_username": "admin",
"aud": "c5c26de3-7d0a-4c6b-bccb-bc5c2d7e3b16",
"email": "admin@example.com"
}
可以读出三个事实:iss 就是 FUSIO_URL 的值;aud 是签发应用的 app_key;exp - iat = 3600,与 fusio_expire_token='PT1H' 精确一致。这也再次印证 B2 部署篇的提醒——FUSIO_URL 配错,签发出的令牌声明与规范文档里的地址都会跟着错。
六、实测二:防火墙参数(fusio_firewall_*)
6.1 工作机制(源码级)
防火墙是 fail2ban 式的内置实现,核心逻辑在 vendor/fusio/impl/src/Service/Firewall.php(实机转录):
$count = $this->firewallLogTable->getResponseCodeCount($tenantId, $ip,
$this->frameworkConfig->getFirewallFindTime());
if ($count > $this->frameworkConfig->getFirewallMaxRetry()) {
// 写入封禁行:name = Ban-<ip中.和:换成->-<到期时间YmdHis>
$row->setName('Ban-' . str_replace(['.', ':'], '-', $ip) . '-' . $now->format('YmdHis'));
$row->setType(Table\Firewall::TYPE_DENY);
$row->setExpire(LocalDateTime::from($now));
$this->firewallTable->create($row);
} else {
$whitelistCodes = $this->frameworkConfig->getFirewallCodes();
if (!empty($whitelistCodes) && !in_array($responseCode, $whitelistCodes)) {
return;
}
// 记一条错误日志到 fusio_firewall_log
$this->firewallLogTable->create($log);
}
三个要点:阈值判断是严格大于(count > maxretry,所以 maxretry=5 实际第 7 次错误才触发);每次客户端错误先记一条 fusio_firewall_log,达到阈值才写 fusio_firewall 封禁行;封禁的检查发生在 OAuth2 授权处理中(ClientCredentials/Password/RefreshToken/AuthorizationCode 四种 grant 都会先过封禁检查)。
6.2 实测设计与过程
为观察行为把参数临时改为 bantime=PT30S / findtime=PT1M / maxretry=5(改完清缓存)。用错误密码连续请求 password grant:
attempt1: 400
attempt2: 400
attempt3: 400
attempt4: 400
attempt5: 400
attempt6: 400
一个容易踩的认知点:Fusio 对错误凭据返回 400 而不是 401,六次错误全是 400、没有任何封禁迹象;第 7 次请求起开始返回封禁响应(HTTP 403):
{
"error": "invalid_request",
"error_description": "Your IP has sent to many requests please try again later"
}
此时数据库中的封禁行与错误计数(实测查询回显,示例为另一轮实验数据):
name type ip expire
------------------------------- ------ ------------ ---------------------
Ban-127-0-0-1-20261024005102 0 127.0.0.1 2026-10-24 00:51:02
Ban-10-89-73-1-20261023201333 0 10.89.73.1 2026-10-23 20:13:33
封禁行的 name 尾部就是到期时间(如 20261024005102 = 2026-10-24 00:51:02),bantime 到期后无需任何干预,请求自动恢复正常(实测 30 秒后同一请求回到 200)。
6.3 封禁期内其他端点的表现
封禁不仅作用于令牌端点。实测封禁期内直接访问首页与健康检查:
root(封禁期): 403
health(封禁期): 403
即封禁是整个入口层面的 403,恢复后两者均回到 200。
6.4 默认参数的含义换算
默认 maxretry=32 / findtime=PT2M / bantime=PT5M 意味着:单个 IP 在 2 分钟内产生 33 次及以上客户端错误(4xx)即封禁 5 分钟。对暴力破解而言这个默认偏宽松,公网暴露的实例建议按 6.2 的量级收紧(例如 maxretry=10 / findtime=PT1M / bantime=PT15M)。
6.5 实战教训:反代后必须配置 FUSIO_TRUSTED_IP_HEADER
上面封禁表里第二行就是真实教训:实测环境中防火墙曾封掉网关 IP 10.89.73.1——所有经由该网关进来的客户端被整体 403。原因:未配置 FUSIO_TRUSTED_IP_HEADER 时,Fusio 看到的客户端 IP 是代理/网关地址,某次实验触发的错误计数全部记在网关头上。处置两步:
- Compose 中加
FUSIO_TRUSTED_IP_HEADER: "X-Forwarded-For"(并重启),让防火墙按真实客户端 IP 计数; - 清理既有封禁与计数:
DELETE FROM fusio_firewall;与DELETE FROM fusio_firewall_log;(MySQL 侧执行;或等待 bantime 自然到期)。
6.6 实验后恢复
配置类实验结束后应恢复默认并清缓存,然后与备份 diff 确认一致(实测恢复后 diff 输出 RESTORED-IDENTICAL),并清理实验产生的防火墙表数据——保持生产配置与第六节 4.1 的默认值表一致。
七、实测三:用户注册开关(fusio_registration)
把 fusio_registration 改为 false 并清缓存后,请求自注册端点:
curl -s -X POST http://127.0.0.1:8148/consumer/register \
-H 'Content-Type: application/json' \
-d '{"username":"u1","email":"u1@example.com","password":"secret1234","name":"u1"}'
实测回显:
{
"success": false,
"title": "Internal Server Error",
"message": "User registration is not enabled"
}
HTTP 状态码 503。恢复 true 后同一请求正常创建用户。结合 《Fusio 7.2.1 介绍与选型指南》 对产品定位的分析:Fusio 的消费端注册面向"开发者自助接入 API"的开放平台场景,纯内部集成场景建议保持 false,由管理员用 system:user_add 建号(命令详见 《Fusio 7.2.1 常用 CLI 命令与 API 实测详解》)。
八、修改配置的标准流程
综合上述机制,任何 configuration.php 层面的修改都建议走这个流程:
cd /opt/fusio # 你的部署目录
# 1. 备份
docker compose exec fusio cp /var/www/html/fusio/configuration.php \
/var/www/html/fusio/configuration.php.bak
# 2. 编辑(把文件复制出来改完再放回,避免容器内编辑器缺失)
docker compose exec fusio cat /var/www/html/fusio/configuration.php > ./configuration.php
# ...本地编辑 ./configuration.php...
docker compose cp ./configuration.php fusio:/var/www/html/fusio/configuration.php
# 3. 清缓存(关键步骤,跳过必踩坑)
docker compose exec fusio rm -f /var/www/html/fusio/cache/container.php
# 4. 验证(按改动内容选择观察点,如令牌端点 expires_in、注册端点状态码等)
三条高频坑(全部实测复现过):
- 改了不生效:没清缓存。
psx_debug=false下缓存不会自动检测变化,必须rm cache/container.php。 - 改 .env 没用:镜像
.env是APP_*前缀,Docker 部署下不参与配置,要改就改 Compose 的FUSIO_*环境变量后重启。 - 令牌有效期改了没变:同坑 1,另外注意
expires_in只在签发时计算,已签发的令牌不受新值影响。
另外两条值得写进运维手册的注意项:
fusio_project_key只在首次安装前设置。安装后更换会让数据库中所有已加密的连接凭据不可读(连接测试会失败),除非逐个重建全部连接。- 环境变量与配置键谁生效:configuration.php 中
env('FUSIO_XXX')的键同时受 Compose 环境变量控制,两处都可改;但FUSIO_BACKEND_*、FUSIO_WORKER_*只在启动脚本消费,改它们必须重启服务才重跑初始化逻辑。
九、相关文档
- 本专栏选型篇:《Fusio 7.2.1 介绍与选型指南》——产品定位、架构与同类对比,理解"为什么要这样配置"的背景;
- 本专栏部署篇:《Fusio 7.2.1 Docker Compose 部署指南》——本文全部实测所依赖的部署环境与目录结构;
- 本专栏命令篇:《Fusio 7.2.1 常用 CLI 命令与 API 实测详解》——
php bin/fusio子命令与 REST API 实测,与本文配置项互为表里。