The background:
Step 1 -> We have a box that runs unit and functional tests of an application by running it in test mode with a specific configuration.
Step 2 -> Upon success of Step 1, we run integration tests of an application by running it in test mode with different configuration set, in another box.
Step 3 -> Upon success of step 2, we run the performance tests of an application by running it in production mode, in the performance test box.
Step 4 -> Upon success of step 3, the build is considered stable and the UAT box is updated with that code base and the application is run in production mode, for the customer review and feedback. Step 5 -> With GO from the customer, the production box is updated with the code base.
背景:步骤1 - >我们有一个框,通过在具有特定配置的测试模式下运行应用程序来运行应用程序的单元和功能测试。步骤2 - >步骤1成功后,我们通过在另一个框中以不同配置集在测试模式下运行应用程序来运行应用程序的集成测试。步骤3 - >步骤2成功后,我们通过在生产模式下,在性能测试框中运行应用程序的性能测试。步骤4 - >步骤3成功后,构建被认为是稳定的,UAT框用该代码库更新,应用程序在生产模式下运行,供客户查看和反馈。步骤5 - >使用来自客户的GO,生产框将使用代码库进行更新。
Now, from above steps we observe that in steps 1 and 2, while the application runs in test mode it has different configuration. Similar is the case with steps 3,4 and 5.
现在,从上述步骤我们观察到,在步骤1和2中,当应用程序在测试模式下运行时,它具有不同的配置。步骤3,4和5的情况类似。
In such situations, what is the recommended practice? We were having YAML configuration files, but personally I felt that maintaining numerous configuration files doesn't make sense. And so, I changed from the practise of
"Config file per environment"
to
"Config file per rails mode, externalizing the variables to linux environment".
在这种情况下,推荐的做法是什么?我们有YAML配置文件,但我个人认为维护大量配置文件没有意义。因此,我从“每个环境的配置文件”的实践改为“每个导轨模式的配置文件,将变量外部化到Linux环境”。
Am I on right track? Doesn't my action, simplify things?
我是在正确的轨道上吗?我不采取行动,简化事情吗?
What are the pros and cons of these two approaches?
这两种方法的优点和缺点是什么?
3 个解决方案
#1
11
In my experience, environment variables are the configuration option of last-resort. They absolutely have their place, but applications should generally check some other more reliable and explicitly intentional configuration option first. I would highly recommend loading configuration from a YAML file and only use an environment variable as a fallback. Always assume that your environment variable is going to apply to everything system-wide and assume that it's going to accidentally get unset or set to the wrong value at some point. i.e., your app shouldn't commit seppuku because some configuration directory got set to /
and it doesn't have permissions to it (or worse you wipe your drive because the app ran as root
). Or more likely, something like your RAILS_ENV
was set to test
when it should've been production
and no one realized and now users are writing data to the wrong place or to /dev/null
on account of all the 500s.
根据我的经验,环境变量是最后的配置选项。它们绝对有它们的位置,但应用程序通常应首先检查一些其他更可靠和明确有意的配置选项。我强烈建议从YAML文件加载配置,并仅使用环境变量作为后备。始终假设您的环境变量将适用于系统范围内的所有内容,并假设它会在某个时刻意外取消设置或设置为错误的值。即,您的应用程序不应提交seppuku,因为某些配置目录设置为/并且它没有权限(或者更糟糕的是您擦除驱动器,因为应用程序以root身份运行)。或者更有可能的是,像你的RAILS_ENV这样的东西被设置为测试什么时候它应该是生产而没有人实现,现在用户正在将数据写入错误的地方或者/ dev / null由于所有500个。
Personally, I like to drop logger.warn
messages anytime I fallback to an environment variable for a configuration value.
就个人而言,我喜欢在我回退到配置值的环境变量时随时删除logger.warn消息。
With your precise issue, honestly, I'd probably pass in the configuration value for which environment to start on the command line.
老实说,对于您的确切问题,我可能会传递配置值,以便在命令行启动哪个环境。
#2
0
At my company, we actually have both, in a way.
在我的公司,我们实际上在某种程度上都有。
We have a Rails app that can point at one of many different installations of another piece of software and use the API from that installation. To specify an installation, about 5 variables need to be set.
我们有一个Rails应用程序可以指向另一个软件的许多不同安装之一,并使用该安装中的API。要指定安装,需要设置大约5个变量。
We had each of these variables as separate environment variables, but setting all of them got old really fast and we inevitably forgot one.
我们将这些变量中的每一个都作为单独的环境变量,但是将它们设置为非常快,我们不可避免地忘记了一个。
So now we have one environment variable we're calling ENV_TOKEN and we have yaml files that contain entries corresponding to the valid ENV_TOKEN variables, and code in config/initializers that sets ENV[key]=value.
所以现在我们有一个环境变量,我们正在调用ENV_TOKEN,我们有yaml文件,包含对应于有效ENV_TOKEN变量的条目,以及config / initializers中设置ENV [key] = value的代码。
So let's say I have variables "FOO" and "BAR" that I want to set to "one" and "two", respectively. I could create a yaml file that contains:
所以,假设我有变量“FOO”和“BAR”,我想分别设置为“一”和“两”。我可以创建一个包含以下内容的yaml文件:
carolclarinet:
FOO: one
BAR: two
and then I would set my environment variable ENV_TOKEN to carolclarinet and FOO and BAR get set to one and two.
然后我将环境变量ENV_TOKEN设置为carolclarinet,FOO和BAR设置为1和2。
I have no idea if this is the best way of doing this, but it works for us.
我不知道这是否是最好的方法,但它对我们有用。
ETA: Note that this is for developing and testing only, the installer of our software takes care of setting all this up so our customers never change any environment variables.
ETA:请注意,这仅用于开发和测试,我们软件的安装程序负责设置所有这些,以便我们的客户永远不会更改任何环境变量。
#3
0
After a lot of googling in vain, discussions with some rails folks and some brainstroming, I have made changes to the code such that I have "A Config file per rails mode, externalizing the application configurations to a yml file, which in my case remains outside of rails environment"
经过大量的谷歌搜索,与一些铁路人员的讨论和一些brainstroming,我已经对代码进行了更改,以便我有“每个导轨模式的一个配置文件,将应用程序配置外部化为yml文件,在我的情况下仍然是在铁路环境之外“
More details of it can be found in my blog post at http://bit.ly/hpChwl
有关它的更多详细信息,请参阅我的博客文章http://bit.ly/hpChwl
Thank you all for sharing your thoughts. Hope my solution interests you all :)
谢谢大家分享你的想法。希望我的解决方案让你感兴趣:)
#1
11
In my experience, environment variables are the configuration option of last-resort. They absolutely have their place, but applications should generally check some other more reliable and explicitly intentional configuration option first. I would highly recommend loading configuration from a YAML file and only use an environment variable as a fallback. Always assume that your environment variable is going to apply to everything system-wide and assume that it's going to accidentally get unset or set to the wrong value at some point. i.e., your app shouldn't commit seppuku because some configuration directory got set to /
and it doesn't have permissions to it (or worse you wipe your drive because the app ran as root
). Or more likely, something like your RAILS_ENV
was set to test
when it should've been production
and no one realized and now users are writing data to the wrong place or to /dev/null
on account of all the 500s.
根据我的经验,环境变量是最后的配置选项。它们绝对有它们的位置,但应用程序通常应首先检查一些其他更可靠和明确有意的配置选项。我强烈建议从YAML文件加载配置,并仅使用环境变量作为后备。始终假设您的环境变量将适用于系统范围内的所有内容,并假设它会在某个时刻意外取消设置或设置为错误的值。即,您的应用程序不应提交seppuku,因为某些配置目录设置为/并且它没有权限(或者更糟糕的是您擦除驱动器,因为应用程序以root身份运行)。或者更有可能的是,像你的RAILS_ENV这样的东西被设置为测试什么时候它应该是生产而没有人实现,现在用户正在将数据写入错误的地方或者/ dev / null由于所有500个。
Personally, I like to drop logger.warn
messages anytime I fallback to an environment variable for a configuration value.
就个人而言,我喜欢在我回退到配置值的环境变量时随时删除logger.warn消息。
With your precise issue, honestly, I'd probably pass in the configuration value for which environment to start on the command line.
老实说,对于您的确切问题,我可能会传递配置值,以便在命令行启动哪个环境。
#2
0
At my company, we actually have both, in a way.
在我的公司,我们实际上在某种程度上都有。
We have a Rails app that can point at one of many different installations of another piece of software and use the API from that installation. To specify an installation, about 5 variables need to be set.
我们有一个Rails应用程序可以指向另一个软件的许多不同安装之一,并使用该安装中的API。要指定安装,需要设置大约5个变量。
We had each of these variables as separate environment variables, but setting all of them got old really fast and we inevitably forgot one.
我们将这些变量中的每一个都作为单独的环境变量,但是将它们设置为非常快,我们不可避免地忘记了一个。
So now we have one environment variable we're calling ENV_TOKEN and we have yaml files that contain entries corresponding to the valid ENV_TOKEN variables, and code in config/initializers that sets ENV[key]=value.
所以现在我们有一个环境变量,我们正在调用ENV_TOKEN,我们有yaml文件,包含对应于有效ENV_TOKEN变量的条目,以及config / initializers中设置ENV [key] = value的代码。
So let's say I have variables "FOO" and "BAR" that I want to set to "one" and "two", respectively. I could create a yaml file that contains:
所以,假设我有变量“FOO”和“BAR”,我想分别设置为“一”和“两”。我可以创建一个包含以下内容的yaml文件:
carolclarinet:
FOO: one
BAR: two
and then I would set my environment variable ENV_TOKEN to carolclarinet and FOO and BAR get set to one and two.
然后我将环境变量ENV_TOKEN设置为carolclarinet,FOO和BAR设置为1和2。
I have no idea if this is the best way of doing this, but it works for us.
我不知道这是否是最好的方法,但它对我们有用。
ETA: Note that this is for developing and testing only, the installer of our software takes care of setting all this up so our customers never change any environment variables.
ETA:请注意,这仅用于开发和测试,我们软件的安装程序负责设置所有这些,以便我们的客户永远不会更改任何环境变量。
#3
0
After a lot of googling in vain, discussions with some rails folks and some brainstroming, I have made changes to the code such that I have "A Config file per rails mode, externalizing the application configurations to a yml file, which in my case remains outside of rails environment"
经过大量的谷歌搜索,与一些铁路人员的讨论和一些brainstroming,我已经对代码进行了更改,以便我有“每个导轨模式的一个配置文件,将应用程序配置外部化为yml文件,在我的情况下仍然是在铁路环境之外“
More details of it can be found in my blog post at http://bit.ly/hpChwl
有关它的更多详细信息,请参阅我的博客文章http://bit.ly/hpChwl
Thank you all for sharing your thoughts. Hope my solution interests you all :)
谢谢大家分享你的想法。希望我的解决方案让你感兴趣:)