上周部署新版本,开发说“本地跑得好好的”,运维说“配置文件里少了个环境变量”,测试又报“数据库连的是测试库不是预发库”——三个人在群里吵了半小时,最后发现是配置文件没随代码一起提交,手动改的配置被 git 忽略了。
配置不是“随便改改”的东西
很多小团队早期把配置直接写死在代码里:数据库地址、API 密钥、超时时间……改个环境就得改代码、重新打包。上线前临时 sed 替换,出问题全靠人肉核对。这种操作,CI 流水线一跑就崩——因为流水线不知道你“心里想的是哪个环境”。
我们怎么让配置管得明白、集成跑得顺
第一步,把所有运行时配置抽出来,按环境分层:
config/
base.yml # 公共配置,如日志级别、基础路径
dev.yml # 本地开发用,DB 指向 Docker 里的 MySQL
test.yml # 测试环境,用独立 Redis 实例
staging.yml # 预发,配置接近生产但不启用支付网关
prod.yml # 生产,敏感字段用占位符,由 CI 注入第二步,在 CI 脚本里做“环境绑定”。比如 GitLab CI 中这样写:
deploy-staging:
stage: deploy
script:
- cp config/base.yml config/app.yml
- cat config/staging.yml >> config/app.yml
- export DB_PASSWORD=$STAGING_DB_PASSWORD
- ./build.sh --env=staging关键点在于:$STAGING_DB_PASSWORD 是 CI 系统里预设的密文变量,不会进仓库,也不会出现在日志里。
别让配置变成“藏宝图”
有次新同事拉下代码,直接 npm start,结果连上了生产 Redis——因为 .env 文件被他误提交了,里面写着 REDIS_URL=redis://prod-01:6379。后来我们加了两条硬规则:
- 所有
.env*文件加入.gitignore,并在项目根目录放一个.env.example(只含示例键名,不含值); - CI 启动服务前,执行脚本检查
config/app.yml是否包含明文密码或prod字样——有就中断构建。
现在每次合并到 main 分支,CI 自动构建 + 启动容器 + 运行健康检查,整个过程没人干预。配置变了?改 yml 提交,流水线自己认环境、填密钥、启服务。
配置即代码,不是口号
配置文件也得走 Code Review。上次有个 PR 改了 base.yml 里的重试次数,从 3 次改成 10 次,大家一开始没当回事,直到压测时发现下游服务被打挂了。现在只要改配置,就得附上理由和影响范围,就像改一行核心逻辑一样认真。
配置管理不是买个配置中心就完事,它得嵌进 CI 的每一次 commit、每一次构建、每一次部署里。哪天你发现改个数据库地址不用找运维改服务器、不用等发布窗口、不担心漏掉某台机器——那说明,它真的跑顺了。