配置 SSOT(TOML + .env) 统一错误契约 Auth 与事务边界 Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client 可观测性(OpenTelemetry + LGTM)
4.5 KiB
4.5 KiB
配置 SSOT(TOML + .env)
Life Echo API 配置分为两层,避免 env 膨胀,同时保留密钥安全边界。
两层 SSOT
| 层 | 来源 | 改什么 | 如何生效 |
|---|---|---|---|
| Secrets / bootstrap | .env.example → .env.development / staging / production |
DATABASE_URL、SECRET_KEY、API 密钥、支付/Liblib 私钥 |
改 env,重启进程 |
| 非密钥配置 | config/default.toml + config/{APP_ENV}.toml |
功能开关、token 过期、SMS 模板 ID、Chat/Memoir 调参、OTel 等 | 改 TOML,发版(随镜像/代码部署) |
APP_ENV 必须在 .env 中设置,用于选择 overlay:development / staging / production。
加载逻辑:app/core/app_config_loader.py 深合并 default.toml 与 {APP_ENV}.toml,经 Pydantic 校验后暴露为 app_config。
文件说明
api/config/
default.toml # 全量默认值(所有 section)
development.toml # 本地差异(OTel、mock 登录、dev COS 等)
staging.toml # 预发差异(CORS、SMS/COS 业务 ID 等)
production.toml # 生产差异
TOML 顶层 section 与代码模块对应:
| Section | 用途 |
|---|---|
[deploy] |
原 Settings 非密钥项(开关、SMS 模板、CORS、OTel endpoint 等) |
[chat] |
访谈 / 对话 |
[memoir] |
回忆录流水线 |
[memory] |
Memory 富化 / compaction |
[story] |
Story / 章节 |
[eval] |
内网评测 / judge |
[llm] [asr] [tts] [celery] [alembic] [agent_log] [otel] [misc] |
运行时默认 |
业务代码仍可通过原有 import 读取(薄 re-export):
from app.features.conversation.constants import chatfrom app.core.runtime_constants import llm_defaultssettings.enable_tts等 deploy 字段通过SettingsFacade代理到 TOML
常见操作
改访谈温度
# config/default.toml 或 config/staging.toml
[chat]
interview_temperature = 0.7
改生产 CORS
# config/production.toml
[deploy]
api_cors_origins = "https://your-domain.com"
改 DeepSeek API Key — 仍在 .env:
DEEPSEEK_API_KEY=sk-...
旧 env 键对照(节选)
| 旧 env 键 | 新位置 |
|---|---|
CHAT_INTERVIEW_PERSONA |
[chat] interview_persona |
CHAT_INTERVIEW_TEMPERATURE |
[chat] interview_temperature |
MEMOIR_ORAL_NORMALIZE_MODE |
[memoir] oral_normalize_mode |
MEMORY_COMPACTION_ENABLED |
[memory] compaction_enabled |
EVAL_JUDGE_MODEL |
[eval] judge_model |
DEEPSEEK_BASE_URL |
[llm] deepseek_base_url |
ENABLE_TTS |
[deploy] enable_tts |
TENCENT_SMS_SDK_APP_ID |
[deploy] tencent_sms_sdk_app_id |
OTEL_ENABLED |
[deploy] otel_enabled |
SECRET_KEY |
仍在 .env |
测试
- 设置
CONFIG_DIR指向 fixture 目录可隔离加载:见tests/test_app_config_loader.py tests/test_settings_allowlist.py防止 Settings 字段反弹
Docker
config/ 随 COPY . . 打入镜像;compose 仍 env_file: .env 注入密钥。确保容器内 APP_ENV 与目标 overlay 文件名一致。
Redis / Celery 分离
| 用途 | 默认 DB | 环境变量 |
|---|---|---|
| 会话、对话历史、task tracker 等业务 key | DB/0 | REDIS_URL |
| Celery broker + result backend | DB/1 | CELERY_REDIS_URL(compose 显式注入;未设时由 REDIS_URL 自动 +1) |
升级注意: 启用 DB 分离后,旧版在 DB/0 上未消费的 Celery 消息会被丢弃(一次性 cutover,无需迁移脚本)。
若 REDIS_URL 使用 DB/15,必须显式设置 CELERY_REDIS_URL(Redis 仅支持 logical DB 0–15,无法 auto +1)。
Shell 脚本与 TOML
| 脚本 | 仍读 .env |
已改读 TOML |
|---|---|---|
development.sh |
APP_ENV、密钥、OTEL_ENABLED(legacy 覆盖) |
deploy.otel_enabled → 是否起 Grafana 栈;eval.internal_enable_docs → 是否打印 /docs 链接 |
deploy.sh |
密钥、DATABASE_URL 等 |
SMS 模板等不再检查 env(在 config/production.toml) |
verify_observability_metrics.sh |
— | 提示文案指向 deploy.otel_enabled |
勿再依赖 .env 中的 OTEL_ENABLED、MOCK_SMS_LOGIN_ENABLED、INTERNAL_EVAL_ENABLE_DOCS 等(应用运行时已从 TOML 读取);测试里 os.environ["OTEL_ENABLED"] 亦已无效,见 tests/conftest.py。