How to set up and use Rails environment variables in production server? - ruby-on-rails

I need to set up an environment variable for my rails app. Both in my local machine and in the production server. I read some tutorials on the internet but NONE has given the complete instruction on how to set and use these variable in the actual production server. I use digital ocean and linux server to host my rails app.
I have spent days trying to figure this out, but still haven't found a clear and complete instruction from setting the variables on my local machine -> push it to git repo -> set and use the variables in production server. So, hope somebody can help me here, thanks!
UPDATE:
This is how I currently setup the environment variables in my rails app by using figoro gem:

You can set system-wide environment variables in the /etc/rc.local file (which is executed when the system boots). If your Rails app is the sole user of the Linux system, that is a good place to store credentials such as API keys because there is no risk of including this file in a public Git repository, as it is outside the application directory. The secrets will only be vulnerable if the attacker gains shell access to your Linux server.
Set the environment variables within /etc/rc.local (do not include the <> characters):
export SOME_LOGIN=<username>
export SOME_PASS=<password>
To see the value of an environment variable, use one of the following commands in the Linux shell:
printenv MY_VAR
echo $MY_VAR
To access those environment variables within Rails, use the following syntax:
Inside .rb files or at the rails console
ENV['MY_VAR']
Inside .yml files:
<%= ENV['MY_VAR'] %>

For anyone still having this issue, figaro now has an easy method in setting the production variables in heroku. Just run:
$ figaro heroku:set -e production

ryzalyusoff.
For Unix
You can use LINUX ENV in rails application.
# .env
GITHUB_SECRET_KEY=SECRET
TWITTER_ACCESS_KEY=XXXXXXXXXXXX
# in rails code
puts ENV["TWITTER_ACCESS_KEY"] # => SECRET
Create .env files for local machine and your production server. Export environment variables like this(on server with ssh):
export GITHUB_SECRET_KEY="XXXXXXXXXXXXXXXXXX"
Anyway, storing keys in config - bad idea. Just add .env.example, others keys configs add to .gitignore. Goodluck.
Example with Rails
For Windows
Syntax
SET variable
SET variable=string
SET /A "variable=expression"
SET "variable="
SET /P variable=[promptString]
SET "
Key
variable : A new or existing environment variable name e.g. _num
string : A text string to assign to the variable.
expression : Arithmetic expression
Windows CMD

I believe we should not push a secret file on git.
To ignore such file use gitignore file and push other code on the git.
On the server side just copy the secret file and create a symlink for that file.
You can find demo here http://www.elabs.se/blog/57-handle-secret-credentials-in-ruby-on-rails

You can set your environment variables in production in the same way, you do it for local system. However, there are couple of gems, which make it easier to track and push to production. Have a look at figaro. This will help you in setting up and deployment of env vars.

You can do this with figaro gem
or in rails 4 there is a file named secret.yml in config folder where you can define your environment variables this file is by default in .gitignore file.For production you need to manually copy that file to server for security reason so that your sensitive information is not available to any one

First create your variable like:
MY_ENV_VAR="this is my var"
And then make it global:
export MY_ENV_VAR
You can check if the process succeeded with:
printenv
Or:
echo MY_ENV_VAR

Related

how to add environment variable in linux for rails app?

i need to set an environment variable for the rails app to use
SECRET_KEY_BASE=9941144eb255ff0ffecasdlkjqweqwelkjasdlkjasd
the config settings for production is as shown below
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
how can i set the environment variable using the linux command
export VARNAME="my value"
I tried to set the variable but looks like it needs to be for the right user. Sorry i am not an expert in linux.
I appreciate any help! Thanks!
export VARNAME="my value"
Well the above works for your current terminal session. After this command, all the subsequent commands can access this variable. Try running this:
echo $VARNAME
It will print the value my value in the console. If you want this behaviour to be persisted, you need to place the export command in your OS' config file (~/.bashrc in case of Ubuntu).
After editing this file, either restart your terminal, or run this:
source ~/.bashrc
This will reload the file in your current terminal session. Alternatively, you can try running your Rails server (or a rake command) as follows:
VARNAME="my value" rails s
For your local development I suggest you to use dotenv (https://github.com/bkeepers/dotenv) or figaro (https://github.com/laserlemon/figaro) and follow the README you find in the gem itself. This gives you much more flexibility than using directly environment variables because you set them only for this specific project and each project can have different of them.
You need to have either a .env file or a application.yml file where you will define your environment variables.
Remember to not commit or push this file to your repository because it contains sensible information!
When you will deploy to production you can use real environment variables or use admin panel control (on Heroku for example)

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.

Rails Production - How to set Secret Key Base?

So I am trying to get my rails app to deploy in production mode, but I get the error: Missing secret_token and secret_key_base for 'production' environment, set these values in config/secrets.yml
My secrets.yml file is as expected:
development:
secret_key_base: xxxxxxx
test:
secret_key_base: xxxxxxx
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
But even after google and research, I have no idea what to do with the production secret key base. Most of the info out there assumes I have certain background knowledge, but the reality is that I'm a noob.
Can anyone explain to me how to set my secret key and get this to work in production mode?
You can generate the key by using following commands
$ irb
>> require 'securerandom'
=> true
>> SecureRandom.hex(64)
=> "3fe397575565365108556c3e5549f139e8078a8ec8fd2675a83de96289b30550a266ac04488d7086322efbe573738e7b3ae005b2e3d9afd718aa337fa5e329cf"
>> exit
The errors you are getting just indicate that the environment variable for secret_key_base are not properly set on the server.
You can use various scripts like capistrano that automate the process of setting these before the application is run.
As for a quick fix try this:
export SECRET_KEY_BASE=YOUR SECRET BASE
Validate the environment variables and check if these have been set.
Command:
env | grep -E "SECRET_TOKEN|SECRET_KEY_BASE"
If your values pop up then these are set on the production server.
Also it is best practice to use ENV.fetch(SECRET_KEY) as this will raise an exception before the app even tries to start.
This answer helped me a lot. He indicates you how to config the secrets.yml file in production and how to read it from the environment:
original link:
https://stackoverflow.com/a/26172408/4962760
I had the same problem and I solved it by creating an environment
variable to be loaded every time that I logged in to the production
server and made a mini guide of the steps to configure it:
https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
I was using Rails 4.1 with Unicorn v4.8.2, when I tried to deploy my
app it didn't start properly and in the unicorn.log file I found this
error message:
"app error: Missing secret_key_base for 'production' environment, set
this value in config/secrets.yml (RuntimeError)"
After some research I found out that Rails 4.1 changed the way to
manage the secret_key, so if you read the secrets.yml file located at
[exampleRailsProject]/config/secrets.yml you'll find something like
this:
Do not keep production secrets in the repository,
instead read values from the environment. production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> This means that rails
recommends you to use an environment variable for the secret_key_base
in your production server, in order to solve this error you should
follow this steps to create an environment variable for Linux (in my
case Ubuntu) in your production server:
1.- In the terminal of your production server execute the next command:
$ RAILS_ENV=production rake secret This returns a large string with
letters and numbers, copy that (we will refer to that code as
GENERATED_CODE).
2.1- Login as root user to your server, find this file and edit it: $ vi /etc/profile
Go to the bottom of the file ("SHIFT + G" for capital G in VI)
Write your environment variable with the GENERATED_CODE (Press "i" key
to write in VI), be sure to be in a new line at the end of the file:
export SECRET_KEY_BASE=GENERATED_CODE Save the changes and close the
file (we push "ESC" key and then write ":x" and "ENTER" key for save
and exit in VI)
2.2 But if you login as normal user, lets call it example_user for this gist, you will need to find one of this other files:
$ vi ~/.bash_profile $ vi ~/.bash_login $ vi ~/.profile These files
are in order of importance, that means that if you have the first
file, then you wouldn't need to write in the others. So if you found
this 2 files in your directory "~/.bash_profile" and "~/.profile" you
only will have to write in the first one "~/.bash_profile", because
Linux will read only this one and the other will be ignored.
Then we go to the bottom of the file ("SHIFT + G" for capital G in VI)
And we will write our environment variable with our GENERATED_CODE
(Press "i" key to write in VI), be sure to be in a new line at the end
of the file:
export SECRET_KEY_BASE=GENERATED_CODE Having written the code, save
the changes and close the file (we push "ESC" key and then write ":x"
and "ENTER" key for save and exit in VI)
3.- You can verify that our environment variable is properly set in Linux with this command:
$ printenv | grep SECRET_KEY_BASE or with:
$ echo $SECRET_KEY_BASE When you execute this command, if everything
went ok, it will show you the GENERATED_CODE from before. Finally with
all the configuration done you should be able to deploy without
problems your Rails app with Unicorn or other.
When you close your shell terminal and login again to the production
server you will have this environment variable set and ready to use
it.
And thats it!! I hope this mini guide help you to solve this error.
Disclaimer: I'm not a Linux or Rails guru, so if you find something
wrong or any error I will be glad to fix it!
nowadays (rails 6) rails generate a secret key base in tmp/development_secret.txt for you.
and in production environment the best is having SECRET_KEY_BASE as en env variable, it will get picked up by rails.
you can check with Rails.application.secret_key_base.
should give you a long string of numbers and characters from 'a' to 'f' (a 128 chars long hexadecimal encoded string)
As you can see, there is a hardcoded value for the development and test environments, but the one for production comes from a variable. First of all, why this way? It is a security feature. This way, if you check this file into version control such as git or svn, the development and test values get shared, which is fine, but the production one (the one that would be used on a real website) isn't, so no one can look at the source to get that secret.
As for the variable used, ENV["SECRET_KEY_BASE"], this is an environment variable from the environment Rails is run in (not to be confused with the Rails "environment", such as development, test, and production). These environment variables come from the shell. As mentioned in JensD's post, you can set this environment variable temporarily with:
export SECRET_TOKEN=YOUR SECRET TOKEN
export SECRET_KEY_TOKEN=YOUR SECRET BASE
To generate a new secret token, use the rake secret command in the command line.
That is temporary, however, and not a good final solution. For a final solution, check out this article which has a quick bit near the end on implementing dotenv to load configuration secrets. Remember, if you use version control, be sure to exclude your .env file from being checked in!
Setting dotenv up takes a little bit of work, but I highly recommend it over trying to manually configure these environment variables.

Ruby on Rails environment variable for development environment

Just a quick question to which I couldn't find an answer on stackoverflow.
If it is easy to have environment variable for staging and production (on heroku for example), how can I set environment variable for my localhost (development environment)? (I am on a mac)
As of today I hardcode my api credential for development environment and I don't feel comfortable with that.
Thanks !
Use dotenv is intended to be used in development:
Add your application configuration to your .env file in the root of your project.
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
You may also add export in front of each line so you can source the file in bash.
in .bashrc
export S3_BUCKET=YOURS3BUCKET
export SECRET_KEY=YOURSECRETKEYGOESHERE
Then access in rails app ENV['S3_BUCKET']
Environment variables are best placed in your .bash_profile file which lives in your home directory on the Mac: /Users/you/.bash_profile. Open that file and add something like this to the end of it:
export MY_ENV_VAR=my_env_value
or
export MY_ENV_VAR="a string with spaces in it"
export is a shell command that sets environment variables. Your .bash_profile is a bash script that runs every time you open a new shell session (open a terminal window) and therefore your export commands will run and set the env vars.
Then they will be available in the ENV constant when you're in Ruby.
Edit /Users/your_user_name/.bash_profile and add there:
export RAILS_ENV=development

env variables available in rails console but not in application

Never had such problem before with vps that I set up from zero, this one (Ubuntu 12.04, 64bit) was installed by some other developer.
The problem
in .bashrc file i have:
export FACEBOOK_ID=123456789
export FACEBOOK_SECRET=987654321
now in terminal if I type env I see these variables.
if I open rails console and type ENV["FACEBOOK_ID"] or ENV["FACEBOOK_SECRET"] I also can see the apropriate values.
The problem is that I have to use FACEBOOK_ID in the app in a view file and I do it with:
<%= ENV["FACEBOOK_ID"] %>
on local machine this returns the right value, in production on vps it returns nothing.
My idea is that the vps was not set up correctly, I couldnt find apache on it or ngnix, and the app is in var/www/apps/app_name/.
What could be wrong and how can I get this env variables in my template?
update
files available in root directory:
.bash_profile .bashrc .cshrc .zprofile .zshrc
Don't put it in local environment. What to do when you deploy the app? What to do when you want to develop another app on your local machine which use Facebook id as well?
Use Figaro gem. It's built for handling such case, env variables and private data. The env variables can be set in YAML file in app and won't be committed to repo. You won't regret.

Resources