It’s relatively straightforward to configure RhoConnect for a single environment (i.e. production), but things get more complicated if you want to have a robust way to deploy to several environments (i.e. development, testing, production).
In this post I’ll show you how to do the following:
- Set up global and environment-specific configurations
- Configure RhoConnect to use a given environment’s settings
Global and Environment-Specific Configurations
First, create a global section (at the root level) within settings/settings.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
Put whatever custom configuration options you want in the global section; this will be used as the base upon which the environment-specific settings get applied.
Note: Any options used natively by the RhoConnect framework (i.e. licensefile, redis, syncserver, iphonecertfile, iphoneserver, raise_on_expired_lock, etc.) must explicitly reside in each environment’s section. This is because RhoConnect independently parses settings.yml and will not use the custom config util we’re going to create below.
There are two main options for configuring which environment a particular RhoConnect instance will target:
- Set the RACK_ENV environment variable (cleaner, but doesn’t work on RhoHub)
- Hard-code it in settings.yml (harder to manage, but works on RhoHub)
Option 1: Setting the RACK_ENV environment variable
Note: This will not work if you’re hosting your RhoConnect application on RhoHub. You must use option #2 in this case.
First, create initializers/hash_extension.rb (borrowed from here):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Second, create util/config_util.rb:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Lastly, add a line to the top of application.rb:
Now that we’ve got all of the required code, the last step is to set the RACK_ENV environment variable accordingly. While developing and using rhoconnect’s built-in rake tasks, you would do something like this to use the uat environment:
In your actual deployed environments, typically the best place to specify environment variables is in the Apache/Nginx config. I like to use Phusion Passenger on top of nginx to host RhoConnect, for which I’d add the rack_env configuration directive provided by passenger. Let’s say we wanted RhoConnect to use settings from the uat section in settings.yml:
1 2 3 4 5 6 7 8 9
There’s a similar directive if you’re using Phusion Passenger on top of Apache called RackEnv (which I again set to target ‘uat’ below):
1 2 3 4 5 6 7 8 9 10 11
If you’re using something other than Passenger to host RhoConnect, it should support setting environment variables for your application; a quick google search should help you there. All you need to do is set the RACK_ENV environment variable to your desired deployment environment (development, uat, production, etc.) so that it’s included in the environment at runtime of the process hosting the RhoConnect application.
Option 2: Hard-code in settings.yml
This will come soon in Part 2 of this series.
Using the CONFIG variable
If you look closely at config_util.rb that we create earlier, you’ll see that it sets a constant named CONFIG. This is a hash that has the configuration keys/values of the section in settings.yml corresponding to the RACK_ENV environment variable merged on top of the values of the global configuration section.
Here’s an example to explain this a bit further:
- You have a settings.yml similar to that described above
- The RACK_ENV environment variable is set to uat
With these assumptions, the CONFIG global, accessible from anywhere in your application, will be a hash with the following contents:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
This represents the contents of the global configuration section with the uat configuration section merged on top of it. Notice that the log:mode configuration value is set to “file”; the global section specifies log:mode to be “stdout”, but that was overridden by the uat configuration section with a log:mode value of “file”. Same thing for rhoadmin_password.
A quick example of how you could use this would be to initialize the rhoadmin password to the current environment’s rhoadmin_password setting (this defaults to blank):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
In the above snippet, the initializer method would set the rhoadmin password to ‘uatadmin’ for our example scenario.
Notice that we didn’t use something like
CONFIG[:uat][:rhoadmin_password]; this would be terrible practice as we would be hard-coding a specific environment in our application and throwing away the flexibility of specifying the target environment at a higher level (i.e. the RACK_ENV environment variable).
Now you can hopefully see how useful this can be. You can use the CONFIG constant anywhere in your application to get access to environment-scoped configuration values, which are easily maintained within the existing settings.yml file used by RhoConnect.
Coming Soon: Part 2, which will go into how you can get a similar setup when you don’t have control over environment variables (i.e. on RhoHub).