跳到正文

环境变量配置参考

官方镜像已经内置了一份运行配置,你不需要编写或挂载任何配置文件——只用环境变量覆盖想改的项即可。docker run -e、docker-compose 的 environment: 段、k8s 的容器 env 都行。改完 docker restart <容器名> 生效。

本页列出镜像接受的全部环境变量、默认值与取值说明。默认值就是镜像内置值(写在 Dockerfile 的 ENV 里),未设即取该默认值。

业务配置(上游、模型、访问密钥、密钥组、负载均衡器、MCP、ACL、脚本、SSO)不在这里——它们存在数据库里、由控制台管理,改完即时生效,与环境变量无关。

先设这几个

零配置主路径下镜像自举控制台与管理员,下面这些只在有对应需求时才设:

  • ENCRYPTION_KEY — 配上游 API key、签发访问密钥前必设,否则保存报 encryption_key not set in configopenssl rand -hex 32 生成
  • CONSOLE_PASSWORD — 想预设控制台管理员密码,而不是用日志里打印的随机密码(仅首次启动生效
  • LICENSE_KEY — 激活授权,解锁多实例/Redis/PostgreSQL 与更高的内存上限
  • STORAGE_MODEPOSTGRES_URLREDIS_URL — 多实例部署必设
  • RESET_ADMIN — 忘记控制台密码时的一次性重置

取值与默认值的两条规则

1. 空值 ≠ 未设 ≠ 代码默认值。 把一个变量设成空串(VAR=)表示「关闭/无」,会被解释成 None。在镜像里你无法把变量「取消设置」来回到某个更深层的代码默认值——镜像的 ENV 就是默认值。例:STREAM_IDLE_TIMEOUT_SECS 的代码内置默认是 300 秒,但镜像发的是 600 秒;想要 300 就显式写 STREAM_IDLE_TIMEOUT_SECS=300,而不是把它留空。

2. 列表型变量用逗号分隔的字符串。 CORS_ORIGINSCORS_HEADERSCORS_METHODSCORS_EXPOSE_HEADERSFALLBACK_DNS_SERVERSTRUSTED_PROXIES 都接受 a,b,c 形式的字符串(会自动按逗号拆分、去空格、丢空项),也接受真数组形式。其余变量都是单值。

监听与请求限制

变量默认值作用与取值
HOST0.0.0.0监听地址;127.0.0.1 仅本机
PORT7890监听端口
MAX_REQUEST_SIZE_MB50最大请求体(MB),所有路由生效
MAX_RESPONSE_BODY_MB25上游响应体上限(MB,仅非流式)
WORKER_THREADS2async 运行时工作线程数。2 是 0.25 vCPU 的安全下限,不是推荐值——按可用 CPU 调大(如 4 vCPU 设 4)
REQUEST_TIMEOUT_SECS空(=不限)单次请求总时长上限;空表示不强制
GRACEFUL_SHUTDOWN_TIMEOUT_SECS收到信号后优雅关停的等待上限
PRE_STOP_DELAY_SECS关停前的延迟,留给负载均衡器摘流
DATA_PLANE_MAX_CONNECTIONS0数据面连接预算:代理路由允许的最大在途请求数,超限的新请求在落盘前立即 429 + Retry-After;控制台/健康检查/监控不受影响。0 = 启动时按 fd(RLIMIT_NOFILE)上限自动推导,实际生效值打印在启动日志。fd 上限本身建议抬高,见 docker 单机教程的 fd 一节
CONNECTION_BUDGET_RESERVE_FDS0自动推导连接预算时,为启动后才会惰性打开的连接(PG 各池、Redis、日志队列)预留的 fd 数;0 = 自动枚举

存储与多实例

变量默认值作用与取值
STORAGE_MODEpostgresql持久化后端:sqlite(单机)/ postgresql(多实例共享)。镜像默认 postgresql + 空 POSTGRES_URL,零配置路径靠未授权时 license 层强制改回 sqlite 才跑通
SQLITE_PATH/var/lib/protoflux/stats.sqliteSQLite 文件路径(单机模式)
POSTGRES_URLPostgreSQL 连接串;sslmode 查询参数控制 TLS(disable/require/verify-full)。多实例必设
POSTGRES_POOL_SIZE10PG 最大并发连接数
POSTGRES_CONSOLE_POOL_SIZE8控制台(登录/用户/审计)查询的独立连接池,与数据面隔离——数据面把主池打满时管理入口仍然可达
POSTGRES_WAIT_TIMEOUT_SECS10连接池获取超时;0 永久等待
POSTGRES_STATEMENT_TIMEOUT_SECS30stats 池服务端单语句超时;0 无限
REDIS_URLRedis 连接串(多实例:会话/限流/日志广播/IP 封禁共享);不设则全内存
REDIS_KEY_PREFIXprotoflux:Redis 键前缀,多套网关共用同一 Redis 时区分
ENCRYPTION_KEY静态敏感数据(访问密钥、上游 API key)加密密钥;用 openssl rand -hex 32 生成

关于 ENCRYPTION_KEY

  • 只通过 -e / secret 注入,不要写进镜像层或 compose 明文
  • 务必备份这把密钥:丢失 = 已加密数据永久不可读
  • 多实例部署时,所有实例必须用同一把密钥
  • 空值时网关能启动,但一旦要读写加密密钥就会 fail-closes 报错——配上游 API key 前先设好

控制台

变量默认值作用与取值
CONSOLE_ENABLEDtrue是否启用控制台;false 则不建管理员、/console 不可达
CONSOLE_PASSWORD控制台管理员 protoflux 的初始密码,仅在首次启动(控制台用户表为空)时生效,之后修改无效;空时首启自动生成强随机密码并打印一次到日志
CONSOLE_SECRET_KEY控制台 API 的 Bearer token(长期有效,供脚本/CI 直调 /console/api/*,命中即管理员权限)。空 = 不启用该认证方式,不会自动生成(会自动生成的是 CONSOLE_PASSWORD 的管理员初始密码)。非空时须 ≥12 字符
CONSOLE_ALLOW_REMOTEtrue是否允许远程访问控制台。设 false 后 Docker Desktop/桥接网络下从宿主机访问会 403
CONSOLE_MAX_FAILURES20连续登录失败上限,达到后封禁来源 IP
CONSOLE_BAN_DURATION300登录封禁时长(秒)
CONSOLE_IP_BAN_ENABLEDtrue是否启用 IP 封禁
CONSOLE_SESSION_AUTO_RENEWtrue会话是否自动续期

跨域与网络信任

变量默认值作用与取值
CORS_ORIGINS允许的跨域来源列表(逗号分隔);空 = 浏览器 CORS 保持关闭
CORS_HEADERS允许的请求头列表(逗号分隔)。始终与网关自带的 Content-TypeAuthorizationz-clientx-gatellm-client 并集
CORS_METHODS允许的方法列表(逗号分隔)
CORS_EXPOSE_HEADERS允许前端读取的响应头列表(逗号分隔)。网关自带的 z-gatewayz-request-id 无论此列表如何都会跨源暴露
CORS_MAX_AGE7200预检结果缓存秒数
CORS_CREDENTIALSfalse是否允许携带凭证
TRUSTED_PROXIES信任的代理 IP/CIDR 列表(逗号分隔,如 10.0.0.0/8,192.168.0.0/16);设了才会信任 X-Forwarded-For 解析客户端真实 IP
IP_RATE_LIMIT_RPM空(=不限)按 IP 的全局每分钟请求上限;空表示不按 IP 限流
METRICS_AUTH_TOKEN/metrics 端点的鉴权 token;设了后需 Authorization: Bearer <token>

上游连接重试与路由亲和

变量默认值作用与取值
UPSTREAM_IDLE_CONNECTIONS16每上游主机的连接池大小
UPSTREAM_SEND_TIMEOUT_SECS180发请求体 + 等响应头(TTFB)超时
UPSTREAM_READ_TIMEOUT_SECS600单次响应块读超时(每块重置);需大于 STREAM_IDLE_TIMEOUT_SECS
UPSTREAM_USER_AGENTProtoflux对上游默认用的 User-Agent
GATEWAY_IDENTITY(OEM 品牌)z-gateway 响应头中的品牌名(<brand>/<version>);默认取镜像的 OEM 品牌(缺省 Protoflux);空 = 不发该头
FALLBACK_DNS_SERVERS1.1.1.1,8.8.8.8,119.29.29.29,223.5.5.5未单独配 DNS 的上游的回退 DNS 池(逗号分隔);空 = 禁用回退
MAX_UPSTREAM_RETRIES3单请求最大上游重试次数(首字节前)
MAX_KEY_ROTATIONS0单请求最大密钥轮换次数(同上游多 key 时);0 = 不限(轮换到所有可用 key)
LB_AFFINITY_TTL_SECS300负载均衡亲和绑定存活秒数;0 = 永久绑定
LOAD_WINDOW_SECS60计算上游负载的窗口秒数
KEY_BINDING_TTL_SECS1800API key 到上游的自动绑定存活秒数
UPSTREAM_BAD_LINK_BUDGET空(=自动)单上游的坏死链接预算:该上游上超过阈值仍未收到首响应的在途请求,最多允许堆积多少个。达到预算后该上游被排除出候选;全部候选都饱和时请求立即 503 + Retry-After,不再排队拖垮健康流量。空 = 自动取初始通行证数的一半;0 = 禁用。纯实时在途计数——请求一结束(任何方式)立即释放名额,上游恢复即满血可用,无任何失败记忆
UPSTREAM_BAD_LINK_THRESHOLD_SECS60坏死链接判定阈值(秒):在途请求超过该时长仍未收到任何首响应,即计为该上游的一个坏死链接
UPSTREAM_DISPATCH_DEADLINE_SECS300单个请求整个出站尝试链(重试 + 密钥轮换 + 连接池恢复)的总时长预算。超时即终止尝试链并返回 504 + Retry-After——挂死请求占用的通行证在有限时间内必然释放。0 = 禁用(仅作逃生门)

流式

变量默认值作用与取值
STREAMING_KEEPALIVE_SECONDS15SSE :keep-alive 注释间隔;需短于反代空闲超时(Nginx 默认 60s,故 15s 安全)
STREAMING_BOOTSTRAP_RETRIES1首字节前重试次数;首块发出后不再重试
STREAMING_LOG_TIMEOUT_SECS3600SSE 流日志后台任务超时(释放"sender 丢失"的僵尸任务)
STREAM_IDLE_TIMEOUT_SECS600两个数据块之间的最大空闲间隔;超过即断流
MAX_STREAM_DURATION_SECS3600单条 SSE 流的总时长硬上限

日志留存与磁盘

变量默认值作用与取值
LOG_LEVELinfo日志级别(error/warn/info/debug/trace
LOG_FORMATjson日志格式(json/plain
LOG_BODY_TO_TERMINALfalse是否把日志体也打到标准输出
LOG_PERSIST_REQUEST_LOGSfalse是否把请求日志持久化到磁盘/数据库
LOG_RETENTION_DAYS7请求日志保留天数;0 = 禁用自动清理
OMS_RETENTION_DAYS30OpenAI 消息存储保留天数;0 = 禁用自动清理
OTEL_ENDPOINTOpenTelemetry 导出端点;空表示不上报
OTEL_SERVICE_NAMEprotoflux上报给 OTEL 的服务名
SENTRY_DSN后端 Sentry 项目 DSN(Rust panic/error);空表示后端不上报(默认编译进二进制)。镜像构建期通过 --build-arg SENTRY_DSN 注入(CI 用 secrets.SENTRY_DSN),运行时 -e 可覆盖
SENTRY_FRONTEND_DSN前端 Sentry 项目 DSN(浏览器 JS error);空则 client-config 回落到 SENTRY_DSN(前后端同一 project),设为不同 project 以隔离前端噪音
SENTRY_ENVIRONMENTproductionSentry 环境标签
SENTRY_RELEASESentry 版本标识;空时运行时默认 protoflux@<版本号>
SENTRY_TRACES_SAMPLE_RATE0Sentry 性能采样率(0.0–1.0);0 = 仅错误/崩溃
LOG_QUEUE_DIR日志队列磁盘目录;空 = 回退到系统临时目录。设了 REDIS_URL 时此项被忽略(多实例走 Redis Pub/Sub)
LOG_QUEUE_SEGMENT_SIZE_MB64日志队列单段文件大小(MB)
LOG_QUEUE_MAX_DISK_SIZE_MB1024日志队列磁盘总量上限(MB)
LOG_STREAM_BODY_MAX_DISK_MB1024SSE 流日志体磁盘溢出上限(MB)
LOG_REQUEST_BODY_MAX_DISK_MB1024请求体磁盘存储上限(MB)
LOG_ACCUMULATOR_MAX_DISK_MB256日志累加器磁盘上限(MB)
LOG_STREAM_BODY_BATCH_SIZE_KB64SSE 流日志体落盘批大小(KB)
LOG_STREAM_BODY_LINGER_MS5SSE 流日志体逗留毫秒
LOG_STREAM_BODY_CHANNEL_CAPACITY_CHUNKS2048SSE 流日志体通道容量(块数)

内存准入与溢写

网关在内存压力下用准入控制 + 磁盘溢写保护进程不被打爆。多数场景默认值即可,仅在突发负载或容器 OOM 时调。

变量默认值作用与取值
MEMORY_SOFT_LIMIT_MB0软内存上限(MB);0 = 不设软上限(由容器 cgroup 兜底)
MEMORY_QUEUE_TIMEOUT_SECS300内存队列项等待准入的超时
MEMORY_QUEUE_MAX_DEPTH空(=自动)慢路径等位队列深度上限(计的是等待处理通行证的请求数,不是并发处理数,四态):空 = 自动取初始通行证数 × 4(有界安全默认);-1 = 不限(显式逃生口);0 = 零等待(不允许排队,拿不到通行证的请求立即被拒);n = 上限 n。超限的新请求立即 429 + Retry-After(reason queue_full),不等 MEMORY_QUEUE_TIMEOUT_SECS。并发处理能力由处理通行证决定,不受此项限制
SPILL_WRITE_CONCURRENCY32磁盘溢写的并发写入数
SPILL_WRITE_STALL_TIMEOUT_SECS10入口落盘写停顿判定超时(秒);槽位等待或写入零进展达到该值即以 503 + Retry-After 拒绝(挂死卷防御),范围 1–300
MEMORY_HOLD_SECS5内存项的持有秒数
MEMORY_RATE_ESCALATE_MB40内存速率升级阈值(MB)
MEMORY_ADMISSION_ENABLEDtrue是否启用准入控制。前馈准入做逐请求结构性决策(admit / 落盘排队),堵死「一批请求都读到陈旧 Normal RSS 后走零开销直通」的突发盲区
MEMORY_FORCE_SPILL_BODY_MB8强制溢写体阈值(MB):body 超此值无条件落盘——nginx client_body_buffer_size 的对应物,body 常驻内存与请求大小上限解耦。0 = 不强制

注:MEMORY_ADMISSION_HANDLER_PERMIT(单 handler 每槽 MB 预算)已移除——并发不再由静态预算派生,而是由预测式 ConcurrencyControllertarget = budget / 实测每请求成本)驱动。如需手动钉死并发,用 TOML memory_admission_handler_permits(>0 禁用 controller)。

脚本沙箱

脚本沙箱限制说明见 脚本运行限制与配置

变量默认值作用与取值
SCRIPT_MAX_OPERATIONS2000每次 QuickJS 脚本执行的最大操作数
SCRIPT_MEMORY_LIMIT_MB64解释器堆上限(MB)
SCRIPT_LAZY_BODYtrue是否对请求/响应体做懒投影

镜像级变量

这几个由进程直接读取,不在配置字段表里。

变量默认值作用与取值
LICENSE_KEY授权密钥(Ed25519)。空 = 未授权:内存上限 512MB、禁用 Redis/PostgreSQL。激活后解锁多实例与更高内存上限
RESET_ADMIN忘记控制台密码时的一次性重置:设成新密码后重启,把管理员 protoflux 密码改成该值。只生效一次(进程写一次性标记),详见 Docker 单机跑通
TZUTC容器时区
MALLOC_CONFbackground_thread:true,narenas:1,...jemalloc 配置(后台线程、arena 数、脏页回收、profiling)
DEV仅存在性生效(设了即开,值无关)。把 /console/* 代理到 Vite 开发服务器——仅本地开发用

仅配置文件可配的字段

下面几个字段只能经 server.toml 配置,官方镜像未把它们暴露为环境变量,因此不在上面的环境变量表里。用配置文件部署(非镜像环境变量路径)时可设:

字段(TOML)默认值作用
server.max_global_concurrency1000全部代理路由的全局并发请求上限,达上限返回 503 overloaded_error;设 0 关闭
streaming.max_concurrent_streams200SSE 流式请求的全局并发上限,达上限返回 503
server.script_pool_size4脚本并发执行槽数,每槽堆内存受 SCRIPT_MEMORY_LIMIT_MB 约束
sso_credentials.refresh_enabledtrue上游 SSO 凭证后台续期任务总开关;每个扫描周期热读取,可不停机关停
sso_credentials.refresh_interval_secs60续期扫描间隔秒数(下限 5)
sso_credentials.refresh_lead_secs300提前续期窗口:在此秒数内到期的凭证立即续期
sso_credentials.refresh_max_parallel4每次扫描的全局并发续期调用上限(单个凭证并发恒为 1,不可配)

这几个并发/槽位上限不是固定值;503 的来源见 错误码 → 503 的来源

各分区的配置参考页

常见问题

Q:想改一个不在本页的更深的参数怎么办? 本页是镜像开放的全部环境变量。另有少数字段只能经 server.toml 配置(见仅配置文件可配的字段);其余更深的调优项未开放,有需要请联系支持。

Q:怎么改配置后生效? 改完环境变量后 docker restart <容器名> 即可。控制台侧的业务配置(上游、模型、密钥等)改完即时生效。

Q:启动报配置错误怎么办? 镜像启动时会自检配置,错误会在日志里给出具体字段与原因。按提示改对应环境变量,再 docker restart <容器名> 即可。

下一步日志与日志体存储 / 脚本运行限制与配置 / 审计与安全配置 / 定价与计费字段 / MCP 配置 / 负载均衡字段 看具体配置参考。