Git:应用程序配置和不同环境
我们在商店中构建的大多数 Web 应用程序都使用 git,尽管应用程序本身使用各种技术(PHP、Rails 等),我们通常为每个站点都有一个临时和生产服务器。通常,这些服务器具有不同的数据库凭证集以及不同的基于环境的配置设置(例如缓存)。我们的工作流程通常涉及为每个项目维护两个 git 分支:master(反映生产服务器)和 staging(反映 staging)。新功能是在暂存(或子分支)上开发的,并在完成和部署后合并回主版本。
我的问题是关于维护特定于分支和环境的配置文件的最佳方法。我已经看到类似问题的答案 此处和此处 ,并且都不能真正满足。主要的两种方法似乎是a)使用.gitignore排除将配置文件保留在git的权限之外,或者b)编写反射性的环境感知代码来确定例如根据主机名使用哪些数据库凭据。我的问题 a) 是它只允许一组配置文件存在于代码库中(无论当前分支如何),因此其他环境的配置文件会丢失。 b) 另一方面,似乎只是需要以与应用程序功能无关的方式对代码库进行不必要的修改。
理想情况下,我想要一种方法来“锁定”某个分支内的配置文件,这样每当我签出 master 时,我都会得到 master 配置文件,每当我签出 staging 时,我都会得到 staging 配置文件。此外,将 staging 合并到 master 中不应以任何方式影响 master 配置文件。迄今为止,我们已经通过在 git 根目录之外设置包含特定于环境的配置文件的文件夹并在部署时手动将适当的文件移动到代码库中来解决这个问题,但这当然是不必要的黑客行为(并且有潜在危险)。
有什么办法可以使用 git 来完成这个任务吗?
感谢您的考虑!
We use git for most of the web applications we build in our shop, and though the applications themselves use a variety of technologies (PHP, Rails, etc), we generally have a staging and production server for each site. Typically, these servers have different sets of database credentials as well as different environment-based configuration settings (e.g. caching). Our workflow generally involves maintaining two git branches per project: master, which reflects the production server, and staging, which reflects staging. New features are developed on staging (or a sub-branch) and are merged back to master upon completion and deployment.
My question is with respect to the best way to maintain the configuration files that are branch- and environment-specific. I've seen the answers from similar questions here and here, and neither really satisfies. The main two approaches seem to be a) using .gitignore exclusion to leave config files outside of git's purview, or b) writing reflective, environment-aware code that determines e.g. what database credentials to use based on hostname. My problem with a) is that it only allows one set of config files to exist in the codebase (irrespective of the current branch), so the other environment's config files get lost. b), on the other hand, just seems to require unnecessary modification of the codebase in a way that doesn't feel related to the application's functionality.
Ideally, I'd like a way to "lock" configuration files within a certain branch, so that whenever I checkout master, I get the master config files, and whenever I checkout staging, I get the staging config files. Additionally, merging staging into master shouldn't affect the master config files in any way. To date, we've dealt with this by having folders containing environment-specific configuration files outside of the git root and manually moving the appropriate files into codebase when deploying, but this is of course needlessly hackish (and potentially dangerous).
Is there any way to accomplish this using git?
Thanks for your consideration!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不知道为什么人们认为他们可以在没有某种安装工具的情况下逃脱。 Git 的目的是跟踪源代码,而不是部署。您仍然应该有一个“make install”类型的工具来从 git 存储库转到实际部署,并且该工具可能会执行各种操作,例如模板扩展或选择备用文件。
例如,您可能已将“config.staging”和“config.Production”签入到 git,并且当您部署到 staging 时,安装工具会选择“config.staging”来复制到“config”。或者您可能有一个“config.template”文件,它将被模板化以在部署中进行“config”。
Not sure why people think they can get away without some sort of install tool. Git is about tracking source, not about deploying. You should still have a "make install"-type tool to go from your git repo to the actual deploy, and this tool might do various things like template expansion, or selection of alternate files.
For example, you might have "config.staging" and "config.production" checked in to git, and when you deploy to staging, the install tool selects "config.staging" to copy to "config". Or you might have a single "config.template" file, which will be templated to make "config" in the deploy.
您可以尝试使用合并后或签出后挂钩来验证一切是否正常,否则进行修复。这实际上似乎是由 ProGit 书建议的。
这个概念基本上是编写这些钩子来充当迷你“make install”脚本,以确保按分支、按主机、按其他文件的存在或内容、按您喜欢的任何内容进行正确的配置。这些钩子甚至可以重写您的配置文件或通过填充模板来重新创建它们。
You could try using the post-merge or post-checkout hooks to verify that all is as it should be, and fix it otherwise. This actually seems to be suggested by the ProGit book.
The concept is basically to write those hooks to act as mini "make install" scripts that ensure the correct configuration by branch, by host, by the presence or contents of other files, by whatever you like. The hooks could even rewrite your config files or recreate them by filling in templates.
我假设通常情况下,
master
仅保存已经在staging
中的提交。如果您向master
添加一个额外的提交,其中包含两个分支之间的配置差异,那么在从staging
中提取的任何内容之上重新调整此提交应该会维护配置。这并不像“将暂存合并到 master 中不应以任何方式影响 master 配置文件”那么简单,但由于在这些情况下您会遇到合并冲突,因此它可能已经足够接近了。I assume that usually,
master
only holds commits that are already instaging
. If you add an extra commit tomaster
which contains the differences in configuration between the two branches, then rebasing this commit on top of whatever is pulled fromstaging
should maintain the configuration. This isn't quite as simple as "merging staging into master shouldn't affect master config files in any way", but as you'd get a merge conflict in these cases, it may be close enough.尝试 https://microconfig.io
它专为管理多个环境的微服务配置而设计。
您可以拥有基本配置文件和特定于环境的覆盖。然后用它生成特定环境的最终结果。
Try out https://microconfig.io
It is designed exactly for managing microservice configuration with multiple environments.
You can have your base configuration files and environment specific overrides. And then use it to generate final results for specific env.