Specify environment variables for bundle exec - ruby-on-rails

I have seen two different ways to specify environment variables when execute bundle exec. Which one is correct on Linux? Maybe both? I am looking for general answer, I know that in this particular case (updating Redmine) specifying RAILS_ENV may be even unnecessary.
bundle exec rake db:migrate RAILS_ENV=production
RAILS_ENV=production bundle exec rake db:migrate

Both options are possible to define environment variables for rake tasks. However, for other executables (such as the rails executable), only the variant to define the variables before the executable is supported.
What is happening here is that when you specify the environment variables at the start, your shell (bash, zsh, ...) set those environment variables for the newly started process. This can be done for any process. processes also inherit the environment variables defined earlier in the shell. A third option could thus be to run this in your shell:
export RAILS_ENV=production
bundle exec rake db:migrate
Now, if you specify the variables as arguments to the rake executable, the shell does not affect, read, or write those. Instead, rake itself inspects its given process arguments and sets the environment variables for its own process before handing control to the actual rake task (db:migrate in this case).
To be more consistent in your ability to define environment variables for the various executables, I personally tend to stick to the option to set environment variables in the shell, rather than using the rake feature to parse its arguments.
Finally, regarding your remark that the RAILS_ENV environment variable might not be necessary here: that is likely not true. Rails applications such as Redmine define different behavior based on the loaded environment, including the database they connect to (as defined in the config/database.yml file), other settings (as defined for Redmine in config/configuration.yml) and internal parameters such as logging verbosity and handling of exceptions. As such, you most likely want to always use RAILS_ENV=production everywhere since Rails (and Redmine) default to the development environment if nothing is specified.

Related

Why is secret_key_base blank on Heroku (Rails 5.2)

I deleted secrets.yml and created credentials.yml.enc.
Locally I am using master.key, and in production I don't have any master key, only a RAILS_MASTER_KEY set as an environment variable.
On Heroku, if I run Rails.application.secrets I get:
{:secret_key_base=>nil, :secret_token=>nil}
and if I run Rails.application.credentials I do in fact see my secret_key_base.
However, locally... if I run the same commands, I DO see secret_key_base when calling Rails.application.secrets.
My main concern is that rails is going to have an empty secret_key_base in production which would be used to encrypt sessions and all kinds of critically important security things. I'm trying to verify that it actually does have the key set.
I'd love a way to 100% confirm that it's working in production, and that it's not blank. Is there some method I can call to check which doesn't rely on calling it via the methods above?
The SECRET_KEY_BASE is stored as an environment variable on Heroku. You can either view these in the interface by going to the settings for that dyno or you can do it in the terminal:
heroku run bash
then
env | grep SECRET_KEY_BASE
If you do not see it there may be an issue but you can generate a new one for Heroku and set it in the environment variables (see Rails.application.key_generator)

Best place to check for env variables in Rails

I use ENV variables for all environments to set up different components of the stack, i.e. Redis, Memcached, etc.
I load all of these in the config/application.rb file, and before that I ensure that all environment variables are present.
I'm running into a problem now where I run a rake task before these variables are set, and so it fails my test. Rake seems to doing it's share correctly. This leads me to believe all of these variables initializations are in the wrong spot.
Now I'm at a loss as to the best place to instantiate all these services or check for their existence.
Init them right after Bundler.require(*Rails.groups) in your application.rb like this https://github.com/bkeepers/dotenv#note-on-load-order
You can check env variables in Rails console, for example:
ENV['YOUR_ENV_VARIABLE']

Pick up rails environment when running whenever

I need to parameterize some of my cron tasks that I'm generating with whenever by values that I usually access with the rails config gem. So I want to do something like:
every 2.hours do
execute 'my/command/with/parameter #{Settings.parameter}'
end
When I try to do this I get:
config/schedule.rb:14:in `initialize': uninitialized constant Whenever::JobList::Settings (NameError)
So I conclude that whenever doesn't run in the Rails environment, which is a shame as I'd like to do some cooler stuff with it (schedule stuff based on the DB state after running rake db:seed, for example). Is there any way to get the whenever to run in the Rails context?
Rails comes with "runner" which allows a non-web-stack script to have access to the Rails app's environment and configuration. It's tailor made for this sort of task.

How to undefine an environment variable in ant

I am running Ant to exec another process. This other process has problems with some environment variables that are present. I want these environment variables to be undefined when I exec the other process.
Of course I can undefine the environment variable prior to running Ant. However I am interested in undefining the variable within Ant prior to execing the other process.
So I have at the time of calling Ant an environment with:
SOME_VAR=a-value
And I have in my build.xml:
..<exec exacutable="program.exe>...
And my program.exe chokes on the fact that SOME_VAR is defined.
The exec task has a newenvironment attribute which when set to true clears the current environment. Use together with nested env elements.

How can I set RAILS_ENV to production for all subsequent rake commands?

As a bonus how do I set this in a config, so that when I log into my production server I don't have to retype it.
in your .bashrc, put:
if [[ $- != *i* ]] ; then
# Shell is non-interactive. Be done now!
return
fi
export RAILS_ENV=production
Be careful, you will always be in production mode when you login !
I tend to want to set it conscientiously with each command also.
Although I don't do much directly on the server, I'm usually using capistrano. So if I was working directly on the server a lot, I might want to set it permanently. Which, BTW, Larry didn't mention how to do:
$ RAILS_ENV=production
$ rake foo
$ rake bar
I use
rake task_name RAILS_ENV=production
That way I have to type the phrase "production" conscientiously. Fewer booboos!
Bonus answer:
Set the environment variable RAILS_ENV to production.
You can do that as a shell alias. Eg "set_production" Exact syntax depends on your shell type.
Or you can set the env variable when you login on the production system.

Resources