配置

Cordy Gateway 的环境变量参考——数据库、Redis、供应商密钥、安全、许可证与运行时行为。

Cordy Gateway 通过环境变量配置。请从 deploy/env.template 开始,它带占位符且不含真实密钥。在生产 Compose 工作流中,.env 提供插值值;下方必需的覆盖文件会把基础生产文件未映射的设置传进容器。

生产环境最少必填项

以下项没有安全默认值,生产部署必须设置:

  • DB_NAMEDB_USERDB_PASSWORD
  • DJANGO_SECRET_KEYDJANGO_ALLOWED_HOSTSDJANGO_ADMIN_URL
  • CHANNEL_ENCRYPTION_KEYS(Admin 与 Gateway 服务使用相同的值)

生成密钥:

# DJANGO_SECRET_KEY
python -c "import secrets; print(secrets.token_urlsafe(50))"

# CHANNEL_ENCRYPTION_KEYS(一个 Fernet 密钥)
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

数据库

变量默认说明
DB_NAME数据库名。由 Gateway 数据平面直接读取。 若未设置,Gateway 会回退到一个开发库名,从而无法连上你的生产库。
DB_USER数据库用户。由 Gateway 直接读取。
DB_PASSWORD数据库口令。由 Gateway 直接读取。
DB_HOSTpostgres(Admin)/ pgbouncer(Gateway)Gateway 经 PgBouncer 连接;Admin 直连 Postgres。
DB_PORT5432
DATABASE_URL仅由 Admin(及迁移/测试工具)使用。Gateway 数据平面解析 DATABASE_URL;它从 DB_* 构建 DSN。请两者一致设置。

陷阱:Gateway 从 DB_NAME / DB_USER / DB_PASSWORD 构建 Postgres DSN,而非从 DATABASE_URL。若这些在 gateway 服务上缺失,它会默认到一个开发库名,无法连接,于是每个请求鉴权失败并返回 401。请把 Admin 的 DB_* 值同样配到 Gateway。

Redis

变量默认说明
REDIS_URLredis://localhost:6379/0Redis 连接 URL。在生产 compose 中为 redis://redis:6379/0
REDIS_POOL_SIZE20连接池大小。20 是经调优的默认值;随附模板将其提高到 500 以应对高并发。

供应商密钥

供应商与通道凭据通常作为 Admin 中加密的 Channel 管理,而非放在环境变量中。以下环境键之所以存在,是因为底层 LiteLLM 集成会自动读取它们;它们是可选的,主要用于开发期播种。生产环境请优先使用按通道的加密凭据。

变量供应商
OPENAI_API_KEYOpenAI
ANTHROPIC_API_KEYAnthropic
OPENROUTER_API_KEYOpenRouter
GEMINI_API_KEYGoogle Gemini
AZURE_API_KEYAZURE_API_BASEAZURE_API_VERSIONAzure OpenAI
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_REGION_NAMEAWS Bedrock
COHERE_API_KEYCohere
GROQ_API_KEYGroq
TOGETHERAI_API_KEYTogether AI
DEEPINFRA_API_KEYDeepInfra
REPLICATE_API_TOKENReplicate
HUGGINGFACE_API_KEYHugging Face

通道与凭据如何工作见供应商

安全

变量默认说明
CHANNEL_ENCRYPTION_KEYS逗号分隔的 Fernet 密钥,用于静态加密通道上游凭据。第一个为活跃(加密)密钥,其余用于轮换。生产必填——Admin 与 Gateway 缺少它都会拒绝启动,且两者必须使用相同的值。
CLIENT_CORS_ORIGINS允许从浏览器调用 Gateway 的 Origin,逗号分隔。为空则拒绝所有跨源浏览器访问(服务器到服务器的调用方不使用 CORS)。字面量 * 在生产环境启动时被拒绝。
CLIENT_CORS_ALLOW_WILDCARD_IN_PRODUCTIONfalse允许生产环境使用 * 客户端 CORS 源的不安全逃生阀。请保持关闭。
TRUSTED_PROXY_CIDRS受信反向代理的 CIDR。仅当 socket 对端匹配其一时,才为记录的客户端 IP 采信 X-Forwarded-For / X-Real-IP;否则使用 socket 对端。防止审计 IP 伪造。
GATEWAY_METRICS_TOKEN抓取器访问 /metrics/prometheus 必须出示的 bearer 令牌。生产端点经公开 nginx 访问时使用此项。它与允许 CIDR 均为空时,生产环境返回 403
GATEWAY_METRICS_ALLOWED_CIDRS无需令牌即可抓取的 CIDR。检查使用直接 socket 对端,且先于令牌校验。位于公开 nginx 之后时,允许 nginx 或其网络也会放行它代理的公共请求;请留空。CIDR 仅用于直接、隔离的受信抓取路径。
DJANGO_SECRET_KEYDjango 加密密钥(Admin)。生产必填。
DJANGO_ALLOWED_HOSTSAdmin 服务的主机名,逗号分隔。生产必填。
DJANGO_ADMIN_URLAdmin URL 路径前缀;必须以 / 结尾。取不显而易见的值。生产必填。
DJANGO_CSRF_TRUSTED_ORIGINSTLS 代理之后允许向 Admin POST 的、带协议的源(例如 https://admin.example.com)。
DJANGO_SECURE_SSL_REDIRECTTrue强制 HTTP→HTTPS 跳转。仅本地无 TLS 测试才设 False
ADMIN_HTTP_PORT8001Admin 发布的主机端口。
GATEWAY_HTTP_PORT8002Gateway(经 nginx)发布的主机端口。

Admin 与成员门户

变量默认值说明
CORDY_GATEWAY_BASE_URLhttp://127.0.0.1:8002/v1/my/ 成员快速开始中显示的基础 URL。生产环境应设为客户端可访问的 HTTPS URL;它不会改变 Gateway 监听地址。
ADMIN_LANGFUSE_TRACE_URL_TEMPLATERequest logs 与成员用量中的可选外部追踪链接。必须是包含字面量 {trace_id} 的 HTTP(S) URL,例如 https://langfuse.example.com/trace/{trace_id}

两者都是 Admin 进程变量,必须通过下方部署覆盖文件传入。

必需的生产 Compose 覆盖文件

docker-compose.prod.yml 没有把 .env 作为容器的 env_file 加载。--env-file .env 只为 ${...} 提供插值,而基础文件没有把 ENVIRONMENT 或下列安全与运行时变量映射进 gateway。因此只用基础文件时,Gateway 会采用 development 默认值:空 CORS 列表回退为 *;未设置指标令牌/CIDR 时指标公开;.env 中未被引用的调优值无效;信用扣减 WAL 保持关闭。

在基础文件旁创建 docker-compose.production-overrides.yml。它修正实际部署配置,但不会更改上游 docker-compose.prod.yml

services:
  admin:
    environment:
      CORDY_GATEWAY_BASE_URL: ${CORDY_GATEWAY_BASE_URL:?set CORDY_GATEWAY_BASE_URL}
      ADMIN_LANGFUSE_TRACE_URL_TEMPLATE: ${ADMIN_LANGFUSE_TRACE_URL_TEMPLATE:-}
  gateway:
    environment:
      ENVIRONMENT: production
      CLIENT_CORS_ORIGINS: ${CLIENT_CORS_ORIGINS:-}
      CLIENT_CORS_ALLOW_WILDCARD_IN_PRODUCTION: ${CLIENT_CORS_ALLOW_WILDCARD_IN_PRODUCTION:-false}
      TRUSTED_PROXY_CIDRS: ${TRUSTED_PROXY_CIDRS:-}
      GATEWAY_METRICS_TOKEN: ${GATEWAY_METRICS_TOKEN:-}
      GATEWAY_METRICS_ALLOWED_CIDRS: ${GATEWAY_METRICS_ALLOWED_CIDRS:-}
      GATEWAY_DEFAULT_ROUTING_STRATEGY: ${GATEWAY_DEFAULT_ROUTING_STRATEGY:-weighted}
      GATEWAY_MAX_BODY_BYTES: ${GATEWAY_MAX_BODY_BYTES:-10485760}
      GATEWAY_MAX_INFLIGHT_PER_KEY: ${GATEWAY_MAX_INFLIGHT_PER_KEY:-50}
      GATEWAY_DEFAULT_MAX_COMPLETION_TOKENS: ${GATEWAY_DEFAULT_MAX_COMPLETION_TOKENS:-4096}
      GATEWAY_PRICE_TTL_SECONDS: ${GATEWAY_PRICE_TTL_SECONDS:-300}
      IDEMPOTENCY_TTL_SECONDS: ${IDEMPOTENCY_TTL_SECONDS:-600}
      GATEWAY_CREDIT_CONSUME_WAL: /var/lib/cordy/credit-consume.jsonl
      OTEL_TRACING_ENABLED: ${OTEL_TRACING_ENABLED:-false}
      OTEL_SERVICE_NAME: ${OTEL_SERVICE_NAME:-cordy-gateway}
      OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-}
      OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-}
      OTEL_SHUTDOWN_TIMEOUT_SECONDS: ${OTEL_SHUTDOWN_TIMEOUT_SECONDS:-2.0}
    volumes:
      - gateway_wal:/var/lib/cordy

volumes:
  gateway_wal:

.env 设置 CORDY_GATEWAY_BASE_URL=https://gateway.example.com/v1;使用 Langfuse 时再设置 ADMIN_LANGFUSE_TRACE_URL_TEMPLATE=https://langfuse.example.com/trace/{trace_id}。拓扑需要时还应设置显式浏览器 Origin 与受信代理 CIDR。公开 nginx 部署应设置强 GATEWAY_METRICS_TOKEN 并让 GATEWAY_METRICS_ALLOWED_CIDRS 保持为空;CIDR 检查看到的是 nginx,而非原始公共客户端。

每次启动、重建或扩容时都应用两个文件:

docker compose \
  -f docker-compose.prod.yml \
  -f docker-compose.production-overrides.yml \
  --env-file .env up -d

具名卷会让 /var/lib/cordy/credit-consume.jsonl 在容器替换后继续存在。随附 Gateway 镜像没有声明 USER,因此以 root 运行并可写入挂载目录。如果你用自定义 UID 重新分发镜像,必须创建 /var/lib/cordy 并授予该 UID 写权限;应用会直接打开目标文件,不会创建缺失的父目录。

Redis 信用扣减缓冲写入失败时,Gateway 会把 JSON Lines 成本记录追加到该 WAL,并让请求继续完成。若路径为空或追加也失败,则会记录 consume_drop_total 对应的少扣款。仓库没有自动 WAL 重放命令。请保留该文件作为计费证据,并与请求日志、信用流水和上游账单核对后再人工调整;不要把它交给未记录的命令。

许可证

Cordy Gateway 使用离线的、HMAC 签名的许可证。许可证默认为仅审计(fail-open);它不会阻断正常部署。

变量默认说明
LICENSE_KEYHMAC 签名的许可证载荷。未授权/开发时留空。
LICENSE_SIGNING_SECRET用于校验许可证的共享密钥,按客户提供。
LICENSE_CUSTOMER_ID匹配载荷的预期客户 id;留空则跳过。
LICENSE_NODE_IDnode-1用于节点数校验的当前节点 id。
LICENSE_ENFORCEMENT_MODEaudit_onlyaudit_only(fail-open,仅记录)或 strict(fail-closed)。

运行时行为

变量默认说明
GATEWAY_DEFAULT_ROUTING_STRATEGYweighted默认通道选择策略:weightedcheapestfastestregion_aware。可用 X-Routing-Strategy 按请求覆盖。
GATEWAY_MAX_BODY_BYTES10485760(10 MiB)请求体硬上限。更大的请求体得到 413<= 0 关闭该上限。
GATEWAY_MAX_INFLIGHT_PER_KEY50每 API 密钥的最大在途并发请求数。<= 0 关闭。
GATEWAY_DEFAULT_MAX_COMPLETION_TOKENS4096当请求未设置 max_tokens 时,用于配额准入的补全令牌估算值。
GATEWAY_PRICE_TTL_SECONDS300成本快照所用有效价格缓存的每进程 TTL。
GATEWAY_CREDIT_CONSUME_WALRedis 缓冲写入失败时用于信用扣减成本的追加式 JSON Lines 备份。生产覆盖文件设置持久路径;路径为空或不可写时可能留下已计数的少扣款。
GRANIAN_WORKERS8每个 Gateway 容器的 Granian worker 进程数。
IDEMPOTENCY_TTL_SECONDS600已存幂等响应 / 锁的存活时间。

可观测性(OpenTelemetry)

追踪默认关闭。生产覆盖文件会把所有受支持的 OTEL_* 字段映射进 gateway。请配置一个 Gateway 容器可达、由运维管理的 OTLP/HTTP collector:

OTEL_TRACING_ENABLED=true
OTEL_SERVICE_NAME=cordy-gateway
OTEL_EXPORTER_OTLP_ENDPOINT=https://telemetry.example.com/v1/traces
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <collector-token>"
OTEL_SHUTDOWN_TIMEOUT_SECONDS=2.0

把更新后的环境应用到 Gateway:

docker compose \
  -f docker-compose.prod.yml \
  -f docker-compose.production-overrides.yml \
  --env-file .env up -d gateway

随附的 docker-compose.tracing.ymldocker-compose.observability.yml 是开发/参考配置。其 collector 所在网络没有接入生产 Gateway,且 observability 配置带 CHANGEME 默认值。若未另外设计并验证网络、密钥、存储与访问控制,不要把它们与生产技术栈组合。

变量默认说明
OTEL_TRACING_ENABLEDfalse为 Gateway 启用 OpenTelemetry 追踪。
OTEL_SERVICE_NAMEcordy-gateway追踪中上报的 service.name
OTEL_EXPORTER_OTLP_ENDPOINT导出追踪的 OTLP HTTP 端点。
OTEL_EXPORTER_OTLP_HEADERS逗号分隔的 OTLP 导出器请求头。
OTEL_SHUTDOWN_TIMEOUT_SECONDS2.0关闭时有界的 flush 超时。

扩展与基础设施

以下项用于调优 compose 技术栈与横向扩展。见部署

变量默认说明
SCALE_GRANIAN_WORKERS4运行多个网关副本时的每副本 worker 数。
ADMIN_WORKERS3Admin 服务的 Gunicorn worker 数。
PGBOUNCER_POOL_SIZE100PgBouncer 默认池大小。
PGBOUNCER_MAX_CLIENT_CONN400PgBouncer 最大客户端连接数。
REDIS_MAXMEMORY512mbRedis 最大内存(采用永不触及资金键的 volatile-lru 驱逐)。

备份

变量默认说明
BACKUP_DIR脚本中为 ./backups逻辑备份写入位置。生产模板推荐 /var/backups/cordy
BACKUP_RETENTION7保留的备份数量。
REQUIRE_PITR0一旦启用 WAL 归档 / 时间点恢复,设为 1 以在验收检查中强制它。

后续步骤

  • 部署——把这些设置应用到生产拓扑。
  • 运维——验证健康、备份、升级与追踪。
  • 安全——安全相关变量的上下文。