在版本控制下处理系统特定信息的最佳实践是什么?

时间:2009-01-07 05:46:13

标签: git version-control configuration-files

我是版本控制的新手,所以如果有一个众所周知的解决方案,我会道歉。特别是对于这个问题,我正在使用git,但我很好奇如何处理所有版本控制系统。

我正在开发服务器上开发Web应用程序。我已经在两个地方定义了Web应用程序的绝对路径名(而不是文档根目录)。在生产服务器上,此路径不同。我对如何处理这件事很困惑。

我可以:

  1. 重新配置开发服务器以与生产
  2. 共享相同的路径
  3. 每次更新作品时编辑两次出现。
  4. 我不喜欢#1,因为我宁愿让应用程序灵活应对未来的任何变化。我不喜欢#2,因为如果我开始使用第三个路径开发第二个开发服务器,我将不得不为每次提交和更新更改此内容。

    处理此问题的最佳方法是什么?我想到了:

    1. 使用自定义关键字和变量扩展(例如在版本控制属性中设置属性$ PATH $并在所有文件中展开它)。 Git不支持这一点,因为它会带来巨大的性能损失。

    2. 使用更新后和预提交挂钩。可能是git的可能解决方案,但每次我查看状态时,它都会报告这两个文件被更改。不太干净。

    3. 从版本控制之外的配置文件中拉出路径。然后我必须将配置文件放在所有服务器上的相同位置。不妨开始时采用相同的路径。

    4. 有没有简单的方法来解决这个问题?我在想它吗?

6 个答案:

答案 0 :(得分:12)

不要对文件系统路径等配置数据进行硬编码,并强制进行多个部署匹配。那是黑暗的一面,那里有很多的苦难。

我觉得构建我的系统很容易并且很容易支持多个配置,并且我经常将配置文件并行提交到源代码控制中,但生产是混淆的(没有真正的密码),并且开发是模板化的(所以a checkout无法覆盖开发人员的配置)。代码始终以与配置无关的方式打包 - 可以在任何地方部署相同的二进制文件。

不幸的是,大多数语言/开发平台都不支持这一点(与Ruby on Rails不同)。因此,你必须在不同程度上自己构建它。

通常,基本原则是将间接合并到您的配置中:在代码中不指定配置,而是指定如何查找配置。并且通常调用几个间接:特定于用户,特定于应用程序,特定于机器,特定于环境。每个都应该以明确定义的位置/方式找到,并且它们之间应该有一个非常明确的优先级(通常是用户通过机器而非应用程序而不是环境)。您通常会发现每个可配置设置都在一个位置具有自然主页,但不要将该依赖项硬编码到您的应用程序中。

我发现设计应用程序以报告其配置并进行验证非常有价值。在大多数情况下,丢失或无效的配置项应导致中止应用程序。尽可能在启动时执行该验证(并中止)=快速失败。硬编码默认只有在可以可靠使用时才会默认。

摘要配置访问,以便大多数应用程序不知道它来自何处或如何处理。我更喜欢创建Config类,将可配置设置作为单独属性公开(在相关时强类型化),然后通过IOC将它们“注入”应用程序类。不要让所有应用程序类直接调用所选平台的原始配置框架;抽象是你的朋友。

在大多数企业级(财富500强)组织中,除了该环境的管理团队之外,没有人会看到生产(甚至测试)环境配置。配置文件永远不会在发行版中部署,它们由管理团队手动编辑。相关的配置文件肯定永远不会与代码并排检查到源代码控制中。管理团队可以使用源代码管理,但它是他们自己的私有存储库。 Sarbanes-Oxley和类似法规也倾向于严格禁止开发人员访问(近)生产系统或任何敏感配置数据。在设计方法时要小心。

享受。

答案 1 :(得分:4)

您应始终将历史记录(源代码管理所针对的内容)与部署分开。

部署涉及:

  • 一组已识别的数据(由SCM提供的标签或标签派上用场)
  • 操作这些数据的过程(至少在正确的位置复制它们,但也扩展一些压缩文件,等等......)

在部署的各种操作中,您应该包括 de-variabilization 阶段。

变量是一个关键字,表示可能会发生变化的任何内容,具体取决于您的部署平台(可以是用于持续集成的PC,用于基本认证的Linux,用于预生产认证的旧Solaris8,以及带有区域的Full F15K Solaris10)用于生产:它很短,它可以变化很多)。有关实际示例,请参阅Jonathan Leffler's answer

变量可以表示路径,JVM版本,一些JVM设置等等,您在SCM中放置的内容应该是包含变量的数据,而不是硬编码设置。

下一步是在您的可执行文件中包含一种方法来检测设置文件中的任何更改,以便在运行某些参数时进行更新(避免所有“关闭/更改设置/重新启动”序列)。
这意味着它们是两种类型的部署变量

  • 静态(不会改变),
  • 动态(在运行时会话期间应理想地考虑)

答案 2 :(得分:2)

尽可能避免使用绝对路径。

不要依赖当前的版本控制来做一些神奇的事情 - 您可能会在将来更改版本控制系统。

最简单的方法对我有用:有一个'config.live'并且'config'被配置用于开发。在部署期间,只需将config.live移动到config,一切都很好。对于更复杂的配置,可能需要每个配置的子目录。

一组部署过程至关重要 - 因为配置只是一个不同的区域。

任何更复杂的东西几乎肯定会导致比它解决的更多问题。

答案 3 :(得分:1)

使用Git等SCM进行版本控制和部署工具such as Capistrano for deployment。尽管Capistrano最初是为Ruby on Rails创建的,但将它用于其他框架和语言是完全没问题的。

主要的是,特定的部署工具可以让您灵活地自动化两端的路径。

答案 4 :(得分:0)

我喜欢Ruby on Rails处理这类问题的方式 - 特定于环境的配置文件。 Rails支持开发,测试和生产数据库连接 - 由database.yml文件中的配置控制。这是一篇关于创建其他特定于环境的配置选项的博客文章,它适用于Rails,但可能会为您提供有关如何为您的环境执行类似操作的一些想法。 http://usablewebapps.com/2008/09/yaml-and-custom-config-for-rails-projects/

答案 5 :(得分:0)

听起来您的生产代码是完整的git存储库,并且为了更新生产而执行git pull?您可能希望尝试单独的构建过程来检查存储库中的代码并创建一个干净的构建(没有.git文件夹)。您可以拥有特定于环境的配置文件,其中包含与其一起复制或创建的路径。