Revel框架不支持Spring Boot式Profile自动加载,仅依赖app.conf中run.mode值匹配[dev]/[prod]等条件块,配置必须显式写入对应块内且无继承,环境变量通过${VAR}引用但需提前导出。

Revel 框架本身不支持像 Spring Boot 那样的 profile 多环境自动加载机制,它的配置切换完全依赖 app.conf 文件中的 run.mode 值 + 条件块语法,且**必须手动确保不同环境的配置段不冲突、不遗漏**——这是最容易出问题的地方。
run.mode 是唯一生效的环境开关
Revel 在启动时只读取一个 app.conf 文件,并根据其中 run.mode 的值(如 dev、prod、test)决定启用哪一段配置。它不会自动合并或覆盖,也不会加载额外文件(比如 app-prod.conf)。
-
run.mode必须在app.conf的全局区(即最顶部无条件块的位置)显式设置,例如:run.mode = prod - 所有环境专属配置必须用
[dev]...、[prod]...这样的条件块包裹,且块名必须与run.mode值严格一致(区分大小写) - 未被匹配的条件块会被忽略,哪怕写成
[production]但run.mode = prod,该块也无效
常见错误:数据库配置没随环境切换
典型现象是本地开发连的是 SQLite,上线后却还在连 SQLite,或者密码没换导致 500 错误。根本原因是数据库配置项没放在对应条件块里,而是写在了全局区。
- ❌ 错误写法(全局配置,永不切换):
db.url = sqlite3://storage.db
- ✅ 正确写法(按环境隔离):
[dev] db.url = sqlite3://storage.db [prod] db.url = postgres://user:pass@127.0.0.1:5432/myapp?sslmode=disable
- 注意:
db.url这类敏感配置,必须在每个环境块中都显式声明,不能依赖“继承”或“默认值”
如何安全注入环境变量到配置中
硬编码密码或地址到 app.conf 不适合生产环境。Revel 支持用 ${ENV_VAR_NAME} 语法引用系统环境变量,但需注意解析时机和 fallback 行为。
- 环境变量在应用启动时一次性展开,不是运行时动态读取
- 若变量未定义,默认为空字符串,不会报错;建议配合
StringDefault在代码里兜底,例如:revel.Config.StringDefault("db.url", "sqlite3://fallback.db") - 推荐组合用法:
[prod] db.url = postgres://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/myapp - 启动前确保已导出:
export DB_USER="prod_user" DB_PASS="s3cr3t" DB_HOST="pg.example.com" DB_PORT="5432"
测试环境配置容易被忽略的细节
很多人只配了 dev 和 prod,但 CI/CD 流水线跑集成测试时用的是 test 模式,结果因缺少 [test] 块而回退到全局默认值,导致测试连接错数据库或日志级别不对。
- 务必为每个实际使用的
run.mode值提供完整配置块,包括test、staging等 - 测试环境应禁用邮件发送、关闭外部 API 调用、使用内存数据库或临时 schema
- 可借助 Revel 的
revel.BUILD_TIME或自定义构建参数生成唯一测试标识,避免测试数据污染
配置切换失效往往不是框架问题,而是条件块命名不一致、关键配置漏写进块内、或环境变量未正确导出——每次部署前用 revel run -a myapp -c /path/to/app.conf 加 -v 参数验证配置加载是否符合预期,比上线后排查快得多。











