Environment variable returns nil - ruby-on-rails

Here's how I set my ENV variable
#~/repos/project
export GA_USERNAME="email#gmail.com"
When I try to use ENV['GA_USERNAME] in my application, it returns nil. However, in the console it strangely prints the variable and then returns nil...
1.9.2-p320 :003 > puts ENV['GA_USERNAME']
email#gmail.com
=> nil
Edit I don't think my ENV variables are persisting. When I restart my computer, variable is nil and needs to be set again.

A traditional way to set env vars for a server process is:
RAILS_ENV=production GA_USERNAME=foobar rails s
If you want to specify the env vars in a persistent way, like in a file, try figaro. The README tells you how to start, but the idea is:
rails generate figaro:install
edit config/application.yml (which the last command created)
in your app, it will automatically set per-environment (production, development, test) variables
UPDATE
dotenv might be an even better and simpler approach:
gem 'dotenv-rails', :groups => [:development, :test]
put cross-environment key-value pairs in .env
put env-specific pairs .env.test or .env.development
See their README for all the details.

Related

Where is SECRET_KEY_BASE environment variable located when I start Rails app in Production

In the Rails 4 In Action Book, it states that after doing some other setup: the final setup to boot up your rails app in production mode (with web brick) is to enter this command in terminal:
SECRET_KEY_BASE='rake secret' rails s -e production
I am trying to see where the environment variable of SECRET_KEY_BASE is stored.
Within /app/config/secrets.yml it says that the secret_key_base variable is an environment variable:
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
But I looked within .bashrc and .bash_profile and the variable SECRET_KEY_BASE is not there.
Ultimately I want to know: where is environment variable and its value? Is it stored somewhere in my rails app? I hope not for security purposes if I push this app to github. I assume it is not stored in the app but in my computer system somewhere. Within a different terminal window I do echo $SECRET_KEY_BASE but nothing gets returned.
Thanks in advance for helping me understand the missing pieces.
As a side note: I am aware of this question, but the question is not as detailed and there is no provided answer.
When you run this:
SECRET_KEY_BASE='rake secret' rails s -e production
you are not actually 'saving' the secret key for future you. You're defining it on a one-time basis. Whenever you run a Ruby command you can set temporary environment variables:
# from shell
KEY="VAL" OTHER_KEY=OTHER_VAL ruby my_command.rb
# from the ruby script
puts ENV["KEY"] # => "VAL"
puts ENV["OTHER_KEY"] # => "OTHER_VAL"
To persist the environment variables you have a couple options. You could hard code them in your source code, but this is probably not a good idea because if you push your code to Github, anyone will be able to see it. That's kind of the point of environment variables, anyway, that you can keep them system specific.
Option A
You can set them in .bashrc or .bash_profile
First get the result of rake secret (will be a random string) and set a shell variable:
KEY=`rake secret` # uses backticks to get command result
Then add a line in bashrc to export it:
echo -e "export SECRET_KEY_BASE=$KEY" >> ~/.bashrc
Option B
This is the one I'd recommend, you can use dotenv or figaro to manage your environment variables in an app-specific way, i.e. without cluttering up your bashrc.
For example with dotenv you'd create a .env file which contains:
# change this to the result of rake secret
SECRET_KEY_BASE=j3e2dd293d
This would be excluded from source control by adding it to gitignore.
Then in your ruby app you call
require 'dotenv'
Dotenv.load
and your ENV["SECRET_KEY_BASE"] will be set.
If you want you can make a .env.example file (included in source control) which shows which environment variables need to be defined. Then when the app is cloned you can run mv .env.example .env and customize .env.

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']

Using Figaro and Secrets.yml to Manage Env Variables

I have a rails 4.1 app and I'm trying to organize my env variables. As of right now I have a secrets.yml file in my config/ folder. I also installed the figaro gem. My goal was to have all my env variables in the application.yml (not checked into git) file and then use the secrets.yml (checked into git) file to map the variables from appliation.yml to the application. When I print the files using Rails.application.secrets It just shows hashes that look like this:
:salesforce_username=>"ENV['SALESFORCE_USERNAME']"
None of my external services are working with this env variables setup. When I view the traces, the actually ENV['ACCOUNT_ID'] are being passed through in the requests like this:
v2/accounts/ENV['ACCOUNT_ID']/envelopes
In addition, I cannot access my env variables using Rails.application.secrets.account_id in my app.
secrets.yml
development:
account_id: <%= ENV['ACCOUNT_ID'] %>
aplication.yml
development:
ACCOUNT_ID: "123456"
application.rb
# preload tokens in application.yml to local ENV
config = YAML.load(File.read(File.expand_path('../application.yml', __FILE__)))
config.merge! config.fetch(Rails.env, {})
config.each do |key, value|
ENV[key] = value.to_s unless value.kind_of? Hash
end
The gem provides a generator:
$ rails generate figaro:install
The generator creates a config/application.yml file and modifies the .gitignore file to prevent the file from being checked into a git repository.
You can add environment variables as key/value pairs to config/application.yml:
GMAIL_USERNAME: Your_Username
The environment variables will be available anywhere in your application as ENV variables:
ENV["GMAIL_USERNAME"]
This gives you the convenience of using the same variables in code whether they are set by the Unix shell or the figaro gem’s config/application.yml. Variables in the config/application.yml file will override environment variables set in the Unix shell.
In tests or other situations where ENV variables might not be appropriate, you can access the configuration values as Figaro method calls:
Figaro.env.gmail_username
Use this syntax for setting different credentials in development, test, or production environments:
HELLO: world
development:
HELLO: developers
production:
HELLO: users
In this case, ENV["HELLO"] will produce “developers” in development, “users” in production and “world” otherwise.
You say the ENV variables are being "passed through in the requests", but when I look at your code snippets I think the variables aren't ever being detected as such in the first place.
If you want to inject a variable into a string, double-check that you are using the following format, especially the # and {}:
important_string = "v2/accounts/#{ENV['ACCOUNT_ID']}/envelopes"
On a more general note, if you're unsure what environment variables are being set in a given environment, the easiest way to double-check is to open up the Rails console and query ENV like so:
$ rails console
> puts ENV.keys # find out what ENV vars are set
=> (returns a long list of var names)
> puts ENV['DEVISE_PEPPER']
=> "067d793e8781fa02aebd36e239c7878bdc1403d6bcb7c380beac53189ff6366be"

Set a Rails environment variable locally (Mac OS X)

I'm trying to set environment variables in Rails. I'm following these docs: http://railsapps.github.io/rails-environment-variables.html
One option it gives is to save environment variables in your ~/.bashrc, using this syntax:
export GMAIL_USERNAME="myname#gmail.com"
I tried adding exactly this to my ~/.bashrc. Then I stop my rails server, close my terminal, open my terminal, start rails server. The environment variable still doesn't seem to be available.
I've checked if it is available by doing rails console in my project root folder, and trying > ENV["GMAIL_USERNAME"] # => outputs nil
How can I set an environment variable locally (in development) so that my Rails project has access to it?
I dont know which shell you are using. In case of bash , you can write this in your ~/.bashrc file
export GMAIL_USERNAME=abc#bah.com
then do this in terminal
source ~/.bashrc
Now, check it console . I am sure it will be there .
Create a new file: config/initializers/settings.rb
GMAIL_USERNAME = case Rails.env
when 'development' then 'myname#gmail.com'
end
Restart your app and console.
You should be able to access it wherever you want:
> GMAIL_USERNAME
=> 'myname#gmail.com'

Environment variable in Rails console and Pow

I can't access env variables in the Rails console, while in the application they work.
In .powenv I have export SENDGRID_PASSWORD="123"
In config/initializers/mail.rb there is:
ActionMailer::Base.smtp_settings = {
:password => ENV['SENDGRID_PASSWORD']
}
So in the console when I type UserMailer.welcome_mail.deliver there is an error 'ArgumentError: SMTP-AUTH requested but missing secret phrase'. However from the application it sends the mail successfully.
How can I make the env variables available in the console?
try
. .powenv
then
rails c
(dot is a command to run script on current environment)
Your Rails console isn't able to access the environment variable because Pow passes information from the .powenv or .powrc file into Rails ... Rails doesn't read those files on its own.
In other words, you're setting the ENV['SENDGRID_PASSWORD'] variable in the .powenv file, but that file is not being touched when you start the Rails console.
You'll need to set up a before_filter in your Application Controller that sets the ENV['SENDGRID_PASSWORD'] (or come up with another, similar, way of reading in the .powenv file from within that before_filter in your Rails app).
For posterity, you can add something like this to either your environment.rb, development.rb, or an initializer (config/initializers/pow.rb) depending on what load order you want:
# Load pow environment variables into development and test environments
if File.exist?(".powenv")
IO.foreach('.powenv') do |line|
next if !line.include?('export') || line.blank?
key, value = line.gsub('export','').split('=',2)
ENV[key.strip] = value.delete('"\'').strip
end
end

Resources