环境变量配置参考
官方镜像已经内置了一份运行配置,你不需要编写或挂载任何配置文件——只用环境变量覆盖想改的项即可。docker run -e、docker-compose 的 environment: 段、k8s 的容器 env 都行。改完 docker restart <容器名> 生效。
本页列出镜像接受的全部环境变量、默认值与取值说明。默认值就是镜像内置值(写在 Dockerfile 的 ENV 里),未设即取该默认值。
业务配置(上游、模型、访问密钥、密钥组、负载均衡器、MCP、ACL、脚本、SSO)不在这里——它们存在数据库里、由控制台管理,改完即时生效,与环境变量无关。
先设这几个
零配置主路径下镜像自举控制台与管理员,下面这些只在有对应需求时才设:
ENCRYPTION_KEY— 要给上游 API key 等敏感数据加密就必设;openssl rand -hex 32生成CONSOLE_PASSWORD— 想预设控制台管理员密码,而不是用日志里打印的随机密码LICENSE_KEY— 激活授权,解锁多实例/Redis/PostgreSQL 与更高的内存上限STORAGE_MODE与POSTGRES_URL、REDIS_URL— 多实例部署必设RESET_ADMIN— 忘记控制台密码时的一次性重置
取值与默认值的两条规则
1. 空值 ≠ 未设 ≠ 代码默认值。 把一个变量设成空串(VAR=)表示「关闭/无」,会被解释成 None。在镜像里你无法把变量「取消设置」来回到某个更深层的代码默认值——镜像的 ENV 就是默认值。例:STREAM_IDLE_TIMEOUT_SECS 的代码内置默认是 300 秒,但镜像发的是 600 秒;想要 300 就显式写 STREAM_IDLE_TIMEOUT_SECS=300,而不是把它留空。
2. 列表型变量用逗号分隔的字符串。 CORS_ORIGINS、CORS_HEADERS、CORS_METHODS、CORS_EXPOSE_HEADERS、FALLBACK_DNS_SERVERS、TRUSTED_PROXIES 都接受 a,b,c 形式的字符串(会自动按逗号拆分、去空格、丢空项),也接受真数组形式。其余变量都是单值。
监听与请求限制
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
HOST | 0.0.0.0 | 监听地址;127.0.0.1 仅本机 |
PORT | 7890 | 监听端口 |
MAX_REQUEST_SIZE_MB | 50 | 最大请求体(MB),所有路由生效 |
MAX_RESPONSE_BODY_MB | 25 | 上游响应体上限(MB,仅非流式) |
WORKER_THREADS | 2 | async 运行时工作线程数。2 是 0.25 vCPU 的安全下限,不是推荐值——按可用 CPU 调大(如 4 vCPU 设 4) |
REQUEST_TIMEOUT_SECS | 空(=不限) | 单次请求总时长上限;空表示不强制 |
GRACEFUL_SHUTDOWN_TIMEOUT_SECS | 空 | 收到信号后优雅关停的等待上限 |
PRE_STOP_DELAY_SECS | 空 | 关停前的延迟,留给负载均衡器摘流 |
存储与多实例
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
STORAGE_MODE | postgresql | 持久化后端:sqlite(单机)/ postgresql(多实例共享)。镜像默认 postgresql + 空 POSTGRES_URL,零配置路径靠未授权时 license 层强制改回 sqlite 才跑通 |
SQLITE_PATH | /var/lib/protoflux/stats.sqlite | SQLite 文件路径(单机模式) |
POSTGRES_URL | 空 | PostgreSQL 连接串;sslmode 查询参数控制 TLS(disable/require/verify-full)。多实例必设 |
POSTGRES_POOL_SIZE | 8 | PG 最大并发连接数 |
POSTGRES_WAIT_TIMEOUT_SECS | 10 | 连接池获取超时;0 永久等待 |
POSTGRES_STATEMENT_TIMEOUT_SECS | 30 | stats 池服务端单语句超时;0 无限 |
REDIS_URL | 空 | Redis 连接串(多实例:会话/限流/日志广播/IP 封禁共享);不设则全内存 |
REDIS_KEY_PREFIX | protoflux: | Redis 键前缀,多套网关共用同一 Redis 时区分 |
ENCRYPTION_KEY | 空 | 静态敏感数据(访问密钥、上游 API key)加密密钥;用 openssl rand -hex 32 生成 |
关于 ENCRYPTION_KEY
- 只通过
-e/ secret 注入,不要写进镜像层或 compose 明文 - 务必备份这把密钥:丢失 = 已加密数据永久不可读
- 多实例部署时,所有实例必须用同一把密钥
- 空值时网关能启动,但一旦要读写加密密钥就会 fail-closes 报错——配上游 API key 前先设好
控制台
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
CONSOLE_ENABLED | true | 是否启用控制台;false 则不建管理员、/console 不可达 |
CONSOLE_PASSWORD | 空 | 控制台管理员 protoflux 的初始密码;空时首次启动自动生成强随机密码并打印一次到日志 |
CONSOLE_SECRET_KEY | 空 | 控制台会话签名密钥;空时自动生成 |
CONSOLE_ALLOW_REMOTE | true | 是否允许远程访问控制台。设 false 后 Docker Desktop/桥接网络下从宿主机访问会 403 |
CONSOLE_MAX_FAILURES | 5 | 连续登录失败上限,达到后封禁来源 IP |
CONSOLE_BAN_DURATION | 300 | 登录封禁时长(秒) |
CONSOLE_IP_BAN_ENABLED | true | 是否启用 IP 封禁 |
CONSOLE_SESSION_AUTO_RENEW | true | 会话是否自动续期 |
跨域与网络信任
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
CORS_ORIGINS | 空 | 允许的跨域来源列表(逗号分隔);空 = 浏览器 CORS 保持关闭 |
CORS_HEADERS | 空 | 允许的请求头列表(逗号分隔) |
CORS_METHODS | 空 | 允许的方法列表(逗号分隔) |
CORS_EXPOSE_HEADERS | 空 | 允许前端读取的响应头列表(逗号分隔) |
CORS_MAX_AGE | 7200 | 预检结果缓存秒数 |
CORS_CREDENTIALS | false | 是否允许携带凭证 |
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_CONNECTIONS | 16 | 每上游主机的连接池大小 |
UPSTREAM_SEND_TIMEOUT_SECS | 180 | 发请求体 + 等响应头(TTFB)超时 |
UPSTREAM_READ_TIMEOUT_SECS | 600 | 单次响应块读超时(每块重置);需大于 STREAM_IDLE_TIMEOUT_SECS |
UPSTREAM_USER_AGENT | Protoflux | 对上游默认用的 User-Agent |
FALLBACK_DNS_SERVERS | 1.1.1.1,8.8.8.8,119.29.29.29,223.5.5.5 | 未单独配 DNS 的上游的回退 DNS 池(逗号分隔);空 = 禁用回退 |
MAX_UPSTREAM_RETRIES | 3 | 单请求最大上游重试次数(首字节前) |
MAX_KEY_ROTATIONS | 0 | 单请求最大密钥轮换次数(同上游多 key 时);0 = 不限(轮换到所有可用 key) |
LB_AFFINITY_TTL_SECS | 300 | 负载均衡亲和绑定存活秒数;0 = 永久绑定 |
LOAD_WINDOW_SECS | 60 | 计算上游负载的窗口秒数 |
KEY_BINDING_TTL_SECS | 1800 | API key 到上游的自动绑定存活秒数 |
流式
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
STREAMING_KEEPALIVE_SECONDS | 15 | SSE :keep-alive 注释间隔;需短于反代空闲超时(Nginx 默认 60s,故 15s 安全) |
STREAMING_BOOTSTRAP_RETRIES | 1 | 首字节前重试次数;首块发出后不再重试 |
STREAMING_LOG_TIMEOUT_SECS | 3600 | SSE 流日志后台任务超时(释放"sender 丢失"的僵尸任务) |
STREAM_IDLE_TIMEOUT_SECS | 600 | 两个数据块之间的最大空闲间隔;超过即断流 |
MAX_STREAM_DURATION_SECS | 3600 | 单条 SSE 流的总时长硬上限 |
日志留存与磁盘
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
LOG_LEVEL | info | 日志级别(error/warn/info/debug/trace) |
LOG_FORMAT | json | 日志格式(json/plain) |
LOG_MAX_BODY_SIZE_MB | 25 | 单条日志捕获的请求/响应体上限(MB) |
LOG_BODY_TO_TERMINAL | false | 是否把日志体也打到标准输出 |
LOG_PERSIST_REQUEST_LOGS | false | 是否把请求日志持久化到磁盘/数据库 |
LOG_RETENTION_DAYS | 7 | 请求日志保留天数 |
OMS_RETENTION_DAYS | 30 | OpenAI 消息存储保留天数 |
OTEL_ENDPOINT | 空 | OpenTelemetry 导出端点;空表示不上报 |
OTEL_SERVICE_NAME | protoflux | 上报给 OTEL 的服务名 |
LOG_QUEUE_DIR | 空 | 日志队列磁盘目录;空 = 回退到系统临时目录。设了 REDIS_URL 时此项被忽略(多实例走 Redis Pub/Sub) |
LOG_QUEUE_SEGMENT_SIZE_MB | 64 | 日志队列单段文件大小(MB) |
LOG_QUEUE_MAX_DISK_SIZE_MB | 1024 | 日志队列磁盘总量上限(MB) |
LOG_STREAM_BODY_MAX_DISK_MB | 1024 | SSE 流日志体磁盘溢出上限(MB) |
LOG_REQUEST_BODY_MAX_DISK_MB | 1024 | 请求体磁盘存储上限(MB) |
LOG_ACCUMULATOR_MAX_DISK_MB | 256 | 日志累加器磁盘上限(MB) |
LOG_STREAM_BODY_BATCH_SIZE_KB | 64 | SSE 流日志体落盘批大小(KB) |
LOG_STREAM_BODY_LINGER_MS | 5 | SSE 流日志体逗留毫秒 |
LOG_STREAM_BODY_CHANNEL_CAPACITY_CHUNKS | 2048 | SSE 流日志体通道容量(块数) |
内存准入与溢写
网关在内存压力下用准入控制 + 磁盘溢写保护进程不被打爆。多数场景默认值即可,仅在突发负载或容器 OOM 时调。
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
MEMORY_SOFT_LIMIT_MB | 0 | 软内存上限(MB);0 = 不设软上限(由容器 cgroup 兜底) |
MEMORY_QUEUE_TIMEOUT_SECS | 300 | 内存队列项等待准入的超时 |
MEMORY_QUEUE_MAX_DEPTH | 0 | 内存队列深度上限;0 = 不限 |
SPILL_WRITE_CONCURRENCY | 4 | 磁盘溢写的并发写入数 |
MEMORY_HOLD_SECS | 5 | 内存项的持有秒数 |
MEMORY_RATE_ESCALATE_MB | 40 | 内存速率升级阈值(MB) |
MEMORY_ADMISSION_ENABLED | true | 是否启用准入控制 |
MEMORY_ADMISSION_THRESHOLD_PCT | 70 | 准入触发阈值(占软上限的百分比) |
MEMORY_ADMISSION_FRESH_READ_PCT | 70 | 新请求的准入配额百分比 |
MEMORY_FORCE_SPILL_BODY_MB | 0 | 强制溢写体阈值(MB);0 = 不强制 |
MEMORY_ADMISSION_HANDLER_PERMIT | 30 | 每请求 handler 的准入许可数 |
脚本沙箱
脚本沙箱限制说明见 脚本运行限制与配置。
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
SCRIPT_MAX_OPERATIONS | 2000 | 每次 QuickJS 脚本执行的最大操作数 |
SCRIPT_MEMORY_LIMIT_MB | 64 | 解释器堆上限(MB) |
SCRIPT_LAZY_BODY | true | 是否对请求/响应体做懒投影 |
每密钥限流
字段说明见 审计与安全配置。
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
RATE_LIMIT_ENABLED | false | 是否启用每密钥限流 |
RATE_LIMIT_RPM | 120 | 每密钥每分钟请求上限 |
RATE_LIMIT_WINDOW_SECS | 60 | 限流窗口秒数 |
镜像级变量
这几个由进程直接读取,不在配置字段表里。
| 变量 | 默认值 | 作用与取值 |
|---|---|---|
LICENSE_KEY | 空 | 授权密钥(Ed25519)。空 = 未授权:内存上限 512MB、禁用 Redis/PostgreSQL。激活后解锁多实例与更高内存上限 |
RESET_ADMIN | 空 | 忘记控制台密码时的一次性重置:设成新密码后重启,把管理员 protoflux 密码改成该值。只生效一次(进程写一次性标记),详见 Docker 单机跑通 |
TZ | UTC | 容器时区 |
MALLOC_CONF | background_thread:true,narenas:1,... | jemalloc 配置(后台线程、arena 数、脏页回收、profiling) |
DEV | 空 | 仅存在性生效(设了即开,值无关)。把 /console/* 代理到 Vite 开发服务器——仅本地开发用 |
各分区的配置参考页
- 日志:日志与日志体存储 — 日志体捕获、SSE 磁盘溢出
- 脚本:脚本运行限制与配置 — 脚本沙箱限制、错误模式、脚本测试入口
- 安全:审计与安全配置 — IP 封禁、密码策略、安全响应头
- 定价:定价与计费字段 — 定价基线、价格快照语义、月度账单字段
- MCP:MCP 配置 — MCP 配置在控制台/数据库侧
- 负载均衡:负载均衡字段 — 重试字段
- SSO 企业登录:配置 SSO 企业登录 — 控制台配置;不需要环境变量
常见问题
Q:想改一个不在本页的更深的参数怎么办? 本页就是镜像开放的全部环境变量。更深的调优项未通过环境变量开放;有需要请联系支持。
Q:怎么改配置后生效? 改完环境变量后 docker restart <容器名> 即可。控制台侧的业务配置(上游、模型、密钥等)改完即时生效。
Q:启动报配置错误怎么办? 镜像启动时会自检配置,错误会在日志里给出具体字段与原因。按提示改对应环境变量,再 docker restart <容器名> 即可。
下一步:日志与日志体存储 / 脚本运行限制与配置 / 审计与安全配置 / 定价与计费字段 / MCP 配置 / 负载均衡字段 看具体配置参考。
