27

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?

RedBassett
  • 3,469
  • 3
  • 32
  • 56
nvrpicurnose
  • 677
  • 2
  • 6
  • 17
  • Possible duplicate of [How to solve error "Missing \`secret\_key\_base\` for 'production' environment" on Heroku (Rails 4.1)](http://stackoverflow.com/questions/23180650/how-to-solve-error-missing-secret-key-base-for-production-environment-on-h) – mbaitoff Feb 01 '16 at 08:19

6 Answers6

33

You can generate the key by using following commands

$ irb
>> require 'securerandom'
=> true
>> SecureRandom.hex(64)
=> "3fe397575565365108556c3e5549f139e8078a8ec8fd2675a83de96289b30550a266ac04488d7086322efbe573738e7b3ae005b2e3d9afd718aa337fa5e329cf"
>> exit
Tarun Rathi
  • 577
  • 4
  • 6
18

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.

kometen
  • 6,536
  • 6
  • 41
  • 51
Jens
  • 1,132
  • 7
  • 14
  • What should my secret token be? I used $rake secret and it gave me a key, but what about the base? – nvrpicurnose Mar 21 '15 at 20:33
  • 4
    `rake secret` creates a safe key string to use as `TOKEN` and `BASE`. Rails just needs these to function properly and do some security stuff behind the scenes. – Jens Apr 21 '15 at 08:00
  • Latest Rails no longer needs `secret_token`; only `secret_key_base` is required. – Franklin Yu Mar 27 '17 at 06:07
  • Thanks for the heads up, I'm updating the original answer. – Jens Mar 27 '17 at 15:05
6

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!

Community
  • 1
  • 1
matias salgado
  • 146
  • 1
  • 7
6

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)

localhostdotdev
  • 1,795
  • 16
  • 21
5

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.

RedBassett
  • 3,469
  • 3
  • 32
  • 56
  • 1
    Is there any step by step tutorial on pushing a rails app to production? I cant piece together all these fragments since I lack the necessary background knowledge – nvrpicurnose Mar 21 '15 at 20:36
  • You can try this tutorial from digitalocean: https://www.digitalocean.com/community/tutorials/how-to-automate-ruby-on-rails-application-deployments-using-capistrano – Jens Mar 22 '15 at 10:08
  • 1
    @nvrpicurnose lol the way to learn is to do it again and again until it starts to get easier. I've been spinning up and tearing down servers over and over for a long time until I finally get it. Takes many hours and lots of tutorials to really get it. At least, that's how it's been for me without someone to really hold my hand and show me. Stick to it and it gets easier. Check out the read me on this demo app I tried to deploy. Might help https://github.com/adiakritos/sw-checkin – Nick Res Nov 10 '15 at 05:24
0

First:

Create secret base key for production:

RAILS_ENV=production rake secret

or in new Rails:

RAILS_ENV=production rails secret

Example output:

c0da499ce973f787c1feaa43182a70b53ad8f23a46a7d0f64e92f858e8c4e441f67ef6907b99b934c9c57511dc33c705ee57201afacf6177dd73c9f6bceeacfb

Second:

You may set it to ENV by name for example PROD_SECRET_KEY_BASE:

export PROD_SECRET_KEY_BASE=ef6907b99b934c9c57511dc33c705ee57201afacf6177dd73c9f6bceeacfb

or with saving to ~/.zshrc(or change on ~/.bashrc):

echo 'export PROD_SECRET_KEY_BASE=ef6907b99b934c9c57511dc33c705ee57201afacf6177dd73c9f6bceeacfb' >> ~/.zshrc

and after get value by name PROD_SECRET_KEY_BASE from ENV:

ENV['PROD_SECRET_KEY_BASE']
=> "ef6907b99b934c9c57511dc33c705ee57201afacf6177dd73c9f6bceeacfb"
shilovk
  • 11,718
  • 17
  • 75
  • 74