6

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

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

我可以:

  1. 重新配置开发服务器以与生产服务器共享相同的路径
  2. 每次更新产品时编辑这两个事件。

我不喜欢#1,因为我宁愿让应用程序灵活应对未来的任何变化。我不喜欢#2,因为如果我开始在具有第三条路径的第二个开发服务器上进行开发,我将不得不在每次提交和更新时更改它。

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

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

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

  3. 从版本控制之外的配置文件中提取路径。然后我必须将配置文件放在所有服务器上的相同位置。还不如从相同的路径开始。

有没有简单的方法来处理这个问题?我是不是想多了?

4

6 回答 6

12

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

我发现构建我的系统以轻松支持多种配置很有用且容易,我经常将配置文件并排提交到源代码管理中,但是生产的被混淆了(没有真正的密码)并且开发的被模板化了(所以结帐可以' t 覆盖开发人员的配置)。代码始终以与配置无关的方式打包——相同的二进制文件可以部署在任何地方。

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

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

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

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

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

享受。

于 2009-01-07T06:44:24.367 回答
4

您应该始终将历史记录(源代码管理的用途)与部署分开。

部署涉及:

  • 一组已识别的数据(SCM 提供的标签或标签派上用场)
  • 处理这些数据的过程(至少将它们复制到正确的位置,还可以扩展一些压缩文件,等等......)

在部署执行的各种操作中,您应该包括一个去变量化阶段。

变量是一个关键字,表示可能会根据您的部署平台(可以是用于持续集成的 PC、用于基本认证的 linux、用于预生产认证的旧 Solaris8 以及带有生产区域的完整 F15K Solaris10)的关键字:它很短,它可以变化很大)。有关实际示例,请参阅Jonathan Leffler 的答案

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

The next step would be to include in your executable a way to detect any change in a setting files in order to update while running some parameters (avoiding the the all "shutdown / change settings / restart" sequence).
That means they are two types of deployment variables:

  • static ones (which will never change),
  • dynamic ones (which should be ideally taken into account during the runtime session)
于 2009-01-07T07:27:58.897 回答
2

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

不要依赖你当前的版本控制来做一些神奇的事情——你将来可能会改变版本控制系统。

最简单的方法对我有用:有一个“config.live”,并且为开发配置了“config”。在部署期间,只需将 config.live 移动到 config 就可以了。对于更复杂的配置,可能需要每个配置的子目录。

一套部署程序是必不可少的——因为配置只是一个不同的领域。

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

于 2009-01-07T06:55:36.170 回答
1

Use an SCM such as Git for version control and a deployment tool such as Capistrano for deployment. Although Capistrano was initially created for Ruby on Rails it's perfectly fine to use it for other frameworks and languages.

The main thing is that a specific deployment tool will give you all flexibility to automate things like paths on both ends.

于 2009-01-07T08:17:16.567 回答
0

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

于 2009-01-07T06:07:40.447 回答
0

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

于 2009-01-07T06:38:53.410 回答