多环境配置管理最佳实践:为何不建议用 Git 分支区分配置
在多环境部署中,最稳妥的做法不是为每个环境建独立分支,而是同一套代码分支配合环境变量或配置文件注入。只有在强隔离需求下才考虑用分支区分配置。
先说结论:配置差异尽量通过构建流程注入,分支主要用于代码版本隔离
- 适合:代码逻辑一致但数据库地址等参数不同的场景
- 先准备:统一配置文件结构,确保各环境字段一致
- 验收:部署后检查实际加载的配置值是否符合预期
配置文件结构模板
建议在项目中建立 config 目录,按环境命名文件。确保所有环境配置文件包含相同的键(Key),避免代码读取时报错。
config/
├── config.dev.yaml # 开发环境
├── config.test.yaml # 测试环境
└── config.prod.yaml # 生产环境
示例内容(config.dev.yaml):
database:
host: localhost
port: 3306
name: app_dev
# 密码不要写在这里,使用环境变量占位
password: ${DB_PASSWORD}
CI/CD 流水线配置示例
在 CI/CD 流水线中,根据部署目标环境,复制对应的配置文件为生效文件名,或使用环境变量覆盖。以下是 GitHub Actions 示例:
name: Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set config based on env
run: |
if [ "$DEPLOY_ENV" == "prod" ]; then
cp config/config.prod.yaml config/config.yaml
else
cp config/config.dev.yaml config/config.yaml
fi
- name: Deploy
run: ./deploy.sh
env:
DEPLOY_ENV: ${{ vars.DEPLOY_ENV }}
敏感信息管理
数据库密码等敏感信息不要提交到 Git,即使是在独立分支中。应使用 secrets 管理工具:
- GitHub Actions:使用 Settings > Secrets and variables,代码中通过 ${{ secrets.DB_PASSWORD }} 引用。
- Jenkins:使用 Credentials Binding 插件,在构建环境中注入变量。
- HashiCorp Vault:应用启动时动态拉取密钥,适合高安全需求场景。
验证与排查
部署完成后,需验证配置是否生效:
- 检查环境变量:登录服务器查看运行进程的环境变量。
printenv | grep APP_ENV - 查看启动日志:确认应用加载的配置路径及值。
tail -f /var/log/app/startup.log - 健康检查接口:如果是 Web 服务,通过接口返回当前环境标识。
curl http://localhost:8080/health
常见坑
1. 敏感信息泄露:切勿将生产环境密码提交到 Git 仓库。即使是在独立分支中,权限控制失误也会导致泄露。
2. 配置字段不一致:dev 环境新增了一个配置项,prod 环境配置文件里没有,导致启动报错。解决方案是保持所有配置文件键值一致,仅值不同。
3. 分支合并遗漏:合并代码时只合并了业务逻辑,忘记合并配置文件变更。建议将配置变更作为代码变更的一部分进行 Code Review。
4. 硬编码环境判断:避免在代码中写死 if (env == 'prod'),应通过配置项控制行为。