Missing `secret_key_base` for 'production' environment on Ubuntu 18.04 server (Rails 6.0), multiple topics tried - ruby-on-rails

This topic has a SOLUTION embeded at the end.
PROBLEM
I'm deploying for the first time a Rails app on a VPS on Ubuntu 18.04. with Nginx.
I followed the good tutorial of Gorails "Deploy Ruby on Rails To Production in 2019".
Everything worked, until I had the "Incomplete response received from application" page.
I checked the nginx logs on /var/log/nginx/error.logand saw the typical message "Missing secret_key_base for 'production' environment, set this string with rails credentials:edit"
As the method of Gorails didn't seems to work (after a bundle exec rails secret on his console app-side, he add a file /my_website/.rbenv-vars with a SECRET_KEY_BASE line, filled with the generated secret key), I decided to follow the multiples topics answering to this question.
Here is the thing, I'm not sure if the followings steps are the goods one.
I run bundle exec rails secreton my console, server-side, as deploy user. So I have my GENERATED_KEY_1
I add to ~/.bashrc : export SECRET_KEY_BASE="GENERATED_KEY_1"
I source ~/.bashrc
I check my key with echo $SECRET_KEY_BASE, and I have the good key displayed (GENERATED_KEY_1)
I edited my credential file as
development:
secret_key_base: ORIGINAL_KEY
test:
secret_key_base: ORIGINAL_KEY
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
and added Dotenv to my Gemfile, required it in application.rb
But none of this worked, after restarted nginx server.
So I restarted the previous step, with the root-user.
But again, it failed.
My questions are:
what I am missing ?
How can I know, if it's searching the key in the good place, as I have always the same error message ?
Which key am I suppose to generate ? App-side ? Server-side ? As root or deploy user ?
Do I have something else to configure in /etc/nginx/sites-available/default ? (I saw on this topic that this guys changed a rails_env production; to rails_env development; but I haven't any rails line)
Thank you, I'm a little bit desperate ^^
SOLUTION
During my many tests, I logged with the root user, and run EDITOR="vim" rails credentials:edit. This command had generated a master.key, which doesn't exist on your Github repo.
But first, I didn't modified it. I think that was the main problem, as the application use it to decrypt your credentials.yml.enc file. When I understood it, I edited the master.key with the content of the master.key on my computer app.
Even after editing credentials.yml.encwith <%= ENV["SECRET_KEY_BASE"] %>, this solution works. This corresponds to the answer of Lyzard Kyng, even if it's a bit different.
I can't run EDITOR="vim" rails credentials:editwith the deploy user, it doesn't work.

Rails 5.2 and later uses encrypted credentials for storing sensitive app's information, which includes secret_key_base by default. These credentials are encrypted with the key stored in master.key file. Git repository, generated by default Rails application setup, includes credentials.yml.enc but ignores master.key. After the deployment, which usually involves git push, Rails production environment should be augmented with this key some way.
So you have two options. You can securely upload master.key to production host via scp or sftp. Or you can establish shell environment variable RAILS_MASTER_KEY within the context of a user that runs rails server process. The former option is preferred, but as you have dotenv-rails gem installed, you'd create .env.production file under app's root and put there a line
RAILS_MASTER_KEY="your_master-key_content"
Don't forget to ensure that gem dotenv-rails isn't restricted within Gemfile by development and test Rails environments.
By the way since passenger module ver. 5.0.0 you can set shell environment variables right from nginx.conf

run rake secret in your local machine and this will generate a key for you
make config/secrets.yml file
add the generated secret key here
production:
secret_key_base: asdja1234sdbjah1234sdbjhasdbj1234ahds…
and redeploy the application after commiting
i had the same issue and resolved by this method.

It would be more secure to generate your key on the server and use it there, rather than push it to your repo from a local machine.
Instead of ~/.bashrc do this for using environment variables;
As root user, navigate to the # directory (can probably just use cd ..)
Enter nano home/<yourAppUser>/.bash_profile to navigate to (and create) the file to store the ENV
As you have already, just write this in the file: export SECRET_KEY_BASE="GENERATED_KEY_1"
You can store your database password here as well.

1_ Set credentials with
rails credentials:edit
2_ Upload master.key file to your production server.
If deploy with capistrano, copy master.key to shared folder (shared_path) and then add this to deploy.rb:
namespace :config do
task :symlink do
on roles(:app) do
execute :ln, "-s #{shared_path}/master.key #{release_path}/config/master.key"
end
end
end
after 'deploy:symlink:shared', 'config:symlink'

In my case, on rails credentials:edit, the file indentation were not accurate which gave the error on deployment. So make sure the indentation is correct on your local before deploying.

Related

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.

secrets.yml environment variable not working in Rails 4.1.4

I am in the process of deploying a Rails app.
I get errors missing secret_key_base in the nginx log file when I have secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> in the secrets.yml file.
I have generated the secret using rake secret in the console and placed in ~/.bashrc as
export SECRET_KEY_BASE="secret"
From the console I run echo $SECRET_KEY_BASE and copy secret to secrets.yml replacing <%= ENV["SECRET_KEY_BASE"] %> with secret.
Then everything works fine and the application runs fine in production environment.
I would rather not keep secret in secret.yml and I do not know how to correct this or what I am doing wrong.
Does anyone have any suggestions?
If you use passenger, add
passenger_set_cgi_param SECRET_KEY_BASE "yoursecret";
to your nginx configuration in the relevant section.
See this section in the passenger user guide.
In production ~/.bashrc might not be read - e.g., you run as a different user, nginx might not read ~/.bashrc before starting, etc. Lots of people run into this issue.
A common approach to this is to handle environment configuration like Rails handles database configuration. Create a config/something.yml file with settings for each environment, then read that yaml in a config/initializers/something.rb initializer and use the values for the specific environment. The rails_config and figaro gems automate this approach. I've often just done it without a gem, as it's not terribly difficult. The key, as with database.yml, is that you never want to check this into source control - use .gitignore with git.
If you want to stick with setting your secret key base using an environment variable, then how you do that depends on your production machine, and how you provision it and deploy your code. With Heroku, it's simple enough to just pop into the Heroku console and set it. For other situations, you could use something like Chef/Puppet/Ansible to set the environment variable for your server. Another approach would be to push that information using Capistrano.
You can put the secret base in /config/initializes/secret_token.rb:
SampleApp::Application.config.secret_key_base = 'Your_Base_here'
EDIT:
This is kind of discouraged in many cases, so edit your .env file and set your key base:
SECRET_KEY_BASE=Your_base_here
and put your secrets.yml back to:
<%= ENV["SECRET_KEY_BASE"] %>
You could alternatively use /config/initializes/secret_token.rb:
SampleApp::Application.config.secret_token = ENV['SECRET_TOKEN']
Which will give you the same result, being more secure.
If you are then planning on pushing this to Heroku:
heroku config:set SECRET_KEY_BASE=$SECRET_KEY_BASE

Missing production secret_key_base in rails

I have recently deployed an app and got an internal server error because of missing production secret_key_base. After hours of testing, I managed to solve this problem with two methods:
Method 1:
I generated a new secret_key with rake secret and replaced it with <%= ENV["SECRET_KEY_BASE"] %> in secrets.yml. Deployed the app again and this time it worked. But I think that this method is wrong.
Method 2:
I generated a new secret_key with rake secret and added it to environments/production.rb like config.secret_key_base = 'd1f4810e662acf46a33960e3aa5bd0************************, without changing secrets.yml (default is production: <%= ENV["SECRET_KEY_BASE"] %>). Deployed the app again and it works fine.
My questions:
Which method is the best?
If the 2nd method is correct, why rails does not generate a secret_key_base in production.rb by default?
Is there any other method to do that?
For local development
Generate a secret using rails secret
Method #1: Store this secret in your .bashrc or .zshrc
see https://apple.stackexchange.com/questions/356441/how-to-add-permanent-environment-variable-in-zsh for
Method #2: Use the dotenv Gem
Once you have this gem installed, you then create a .env file in the root of your Rails app that does NOT get checked-into the source control.
https://github.com/bkeepers/dotenv
Method #3 (if using rhc Openshift client)
rhc set-env SECRET_KEY_BASE=3dc8b0885b3043c0e38aa2e1dc64******************** -a myapp
For the server
Method #1: Heroku
Option 1: Store the SECRET_KEY_BASE directly onto the environment
heroku config:set SECRET_KEY_BASE=xxxx
Option 2: Store the secret encrypted with the app and use the master.key file to decrypt it.
Method #2:
For AWS, use AWS Secret Manager to store the master key.
Method #3: For RHC Openshift
connect to your server via SSH and run env so you should see your SECRET_KEY_BASE in the list.
Now restart you app rhc app-stop myapp and rhc app-start myapp
If you're on a normal Ubuntu machine just put export SECRET_KEY_BASE=" <<< output from rake secret here >>> " in your ~/.bashrc.
Run source ~/.bashrc and restart the app.
There is another option that should be a little more secure and that is to add it to the Apache/Nginx configuration file. I'm using Apache and have just used:
SetEnv SECRET_KEY_BASE my_secret
Then just leave the secrets.yml file set to:
production: <%= ENV["SECRET_KEY_BASE"] %>
For a production web server I'm not sure it's valid to assume that a .bashrc file is run and will get your ENV variable set, but I think this way is certain to set it. I'm not and expert so ready to have any risks or reasons why it's not a good idea pointed out to me.
Method 1 is correct. You don't want to store your secrets in the code.

rails secret_key_base not being recognized in production

So I am trying to deploy my rails app in production. When I go to the page I get a 500 error. When I go to my error logs I get the following error:
Exception RuntimeError in Rack application object (Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`)
I am running Rails 4.1 and my config/secrets.yml looks like this:
development:
secret_key_base: <development key>
test:
secret_key_base: <test key>
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
I ran rake secret to get the key and put the export in my bash_profile and sourced it. I ran rake assets:precompile successfully. Yet I still keep getting this error. Any ideas?
Update: I tried to update the error message provided to give slightly better information....and the message didn't update. I then tried adding the key directly to the yml file instead of using an environment variable and still no dice. Im running on hostmonster so I can't restart the server.....but something is telling me thats what needs to be done...
Update 2: After sleeping through the night it seems that this issue is no longer an issue. It must have been some sort of caching. Now my issue is that its trying to use an old config that i changed days ago for my database. If I figure out how to nullify the cache I will post it here and mark it as an answer. If someone else knows how to do it please let me know and I will mark it as an answer. I am using HostMonster as my hosting and followed the steps they have on their site for hosting my rails app.
I had the same problem and I solved creating an environment variable to be loaded every time that I login to the production server and made a mini guide of the steps to configure it by your self:
So I was using Rails 4.1 with Unicorn v4.8.2 and when I tried to deploy my app it doesn't start properly and into 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 a little research I found that Rails 4.1 change the way to manage the secret_key, so if we read the secrets.yml file located at exampleRailsProject/config/secrets.yml (you need to replace "exampleRailsProject" for your project name) you will 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 our production server, so in order to solve this error you will need to follow this steps to create an environment variable for linux (in my case it is Ubuntu) in our production server:
1.- In the terminal of our production server you will execute the next command:
$ RAILS_ENV=production rake secret
This will give a large string with letters and numbers, this is what you need, so copy that (we will refer to that code as GENERATED_CODE).
2.1- Now if we login as root user to our server we will need to find this file and open it:
$ vi /etc/profile
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 we 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 we login as normal user, lets call it example_user for this gist, we 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 we 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.-We 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 that we generated before. Finally with all the configuration done you can deploy without problems your Rails app with Unicorn or other.
Now 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.
You need to restart your server, because after YourAppName::Application.initialize! called in config/environment.rb you can not change your settings.
Checkout your yml markup, probably there some errors
Probably something wrong in your config/initializers/secret_token.rb
The problem is not with ENV pseudo-hash. secret_key_base will be nil if in ENV no such a key.

How to solve error "Missing `secret_key_base` for 'production' environment" (Rails 4.1)

I created a Rails application, using Rails 4.1, from scratch and I am facing a strange problem that I am not able to solve.
Every time I try to deploy my application on Heroku I get an error 500:
Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`
The secret.yml file contains the following configuration:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
On Heroku I configured the "SECRET_KEY_BASE" environment variable with the result of the rake secret command. If I launch heroku config, I can see the variable with the correct name and value.
Why am I still getting this error?
I had the same problem and solved it by creating an environment variable to be loaded every time I logged in to the production server, and made a mini-guide of the steps to configure it:
I was using Rails 4.1 with Unicorn v4.8.2 and when I tried to deploy my application 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 these steps to create an environment variable for Linux (in my case Ubuntu) in your production server:
In the terminal of your production server execute:
$ RAILS_ENV=production rake secret
This returns a large string with letters and numbers. Copy that, which we will refer to that code as GENERATED_CODE.
Login to your server
If you login as the root user, find this file and edit it:
$ vi /etc/profile
Go to the bottom of the file using Shift+G (capital "G") in vi.
Write your environment variable with the GENERATED_CODE, pressing i to insert 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 using Esc and then ":x" and Enter for save and exit in vi.
But if you login as normal user, let's call it "example_user" for this gist, you will need to find one of these other files:
$ vi ~/.bash_profile
$ vi ~/.bash_login
$ vi ~/.profile
These files are in order of importance, which means that if you have the first file, then you wouldn't need to edit the others. If you found these two 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 using Shift+G again and write the environment variable with our GENERATED_CODE using i again, and be sure add 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 using Esc again and ":x" and Enter to save and exit.
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 application with Unicorn or some other tool.
When you close your shell and login again to the production server you will have this environment variable set and ready to use it.
And that's it! I hope this mini-guide helps you 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.
I'm going to assume that you do not have your secrets.yml checked into source control (ie. it's in the .gitignore file). Even if this isn't your situation, it's what many other people viewing this question have done because they have their code exposed on Github and don't want their secret key floating around.
If it's not in source control, Heroku doesn't know about it. So Rails is looking for Rails.application.secrets.secret_key_base and it hasn't been set because Rails sets it by checking the secrets.yml file which doesn't exist. The simple workaround is to go into your config/environments/production.rb file and add the following line:
Rails.application.configure do
...
config.secret_key_base = ENV["SECRET_KEY_BASE"]
...
end
This tells your application to set the secret key using the environment variable instead of looking for it in secrets.yml. It would have saved me a lot of time to know this up front.
Add config/secrets.yml to version control and deploy again. You might need to remove a line from .gitignore so that you can commit the file.
I had this exact same issue and it just turned out that the boilerplate .gitignore Github created for my Rails application included config/secrets.yml.
This worked for me.
SSH into your production server and cd into your current directory, run bundle exec rake secret or rake secret, you will get a long string as an output, copy that string.
Now run sudo nano /etc/environment.
Paste at the bottom of the file
export SECRET_KEY_BASE=rake secret
ruby -e 'p ENV["SECRET_KEY_BASE"]'
Where rake secret is the string you just copied, paste that copied string in place of rake secret.
Restart the server and test by running echo $SECRET_KEY_BASE.
While you can use initializers like the other answers, the conventional Rails 4.1+ way is to use the config/secrets.yml. The reason for the Rails team to introduce this is beyond the scope of this answer but the TL;DR is that secret_token.rb conflates configuration and code as well as being a security risk since the token is checked into source control history and the only system that needs to know the production secret token is the production infrastructure.
You should add this file to .gitignore much like you wouldn't add config/database.yml to source control either.
Referencing Heroku's own code for setting up config/database.yml from DATABASE_URL in their Buildpack for Ruby, I ended up forking their repo and modified it to create config/secrets.yml from SECRETS_KEY_BASE environment variable.
Since this feature was introduced in Rails 4.1, I felt it was appropriate to edit ./lib/language_pack/rails41.rb and add this functionality.
The following is the snippet from the modified buildpack I created at my company:
class LanguagePack::Rails41 < LanguagePack::Rails4
# ...
def compile
instrument "rails41.compile" do
super
allow_git do
create_secrets_yml
end
end
end
# ...
# writes ERB based secrets.yml for Rails 4.1+
def create_secrets_yml
instrument 'ruby.create_secrets_yml' do
log("create_secrets_yml") do
return unless File.directory?("config")
topic("Writing config/secrets.yml to read from SECRET_KEY_BASE")
File.open("config/secrets.yml", "w") do |file|
file.puts <<-SECRETS_YML
<%
raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"]
%>
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
SECRETS_YML
end
end
end
end
# ...
end
You can of course extend this code to add other secrets (e.g. third party API keys, etc.) to be read off of your environment variable:
...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>
This way, you can access this secret in a very standard way:
Rails.application.secrets.third_party_api_key
Before redeploying your app, be sure to set your environment variable first:
Then add your modified buildpack (or you're more than welcome to link to mine) to your Heroku app (see Heroku's documentation) and redeploy your app.
The buildpack will automatically create your config/secrets.yml from your environment variable as part of the dyno build process every time you git push to Heroku.
EDIT: Heroku's own documentation suggests creating config/secrets.yml to read from the environment variable but this implies you should check this file into source control. In my case, this doesn't work well since I have hardcoded secrets for development and testing environments that I'd rather not check in.
You can export the secret keys to as environment variables on the ~/.bashrc or ~/.bash_profile of your server:
export SECRET_KEY_BASE = "YOUR_SECRET_KEY"
And then, you can source your .bashrc or .bash_profile:
source ~/.bashrc
source ~/.bash_profile
Never commit your secrets.yml
For rails6, I was facing the same problem as I was missing the following files. Once I added them the issue was resolved:
1. config/master.key
2. config/credentials.yml.enc
Make sure you have these files!
What I did :
On my production server, I create a config file (confthin.yml) for Thin (I'm using it) and add the following information :
environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction
I then launch the app with
thin start -C /whereeveristhefieonprod/configthin.yml
Work like a charm and then no need to have the secret key on version control
Hope it could help, but I'm sure the same thing could be done with Unicorn and others.
I have a patch that I've used in a Rails 4.1 app to let me continue using the legacy key generator (and hence backwards session compatibility with Rails 3), by allowing the secret_key_base to be blank.
Rails::Application.class_eval do
# the key_generator will then use ActiveSupport::LegacyKeyGenerator.new(config.secret_token)
fail "I'm sorry, Dave, there's no :validate_secret_key_config!" unless instance_method(:validate_secret_key_config!)
def validate_secret_key_config! #:nodoc:
config.secret_token = secrets.secret_token
if config.secret_token.blank?
raise "Missing `secret_token` for '#{Rails.env}' environment, set this value in `config/secrets.yml`"
end
end
end
I've since reformatted the patch are submitted it to Rails as a Pull Request
I've created config/initializers/secret_key.rb file and I wrote only following line of code:
Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]
But I think that solution posted by #Erik Trautman is more elegant ;)
Edit:
Oh, and finally I found this advice on Heroku: https://devcenter.heroku.com/changelog-items/426 :)
Enjoy!
this is works good https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
for root user should edit
$ /etc/profile
but if you non root should put the generate code in the following
$ ~/.bash_profile
$ ~/.bash_login
$ ~/.profile
On Nginx/Passenger/Ruby (2.4)/Rails (5.1.1) nothing else worked except:
passenger_env_var in /etc/nginx/sites-available/default in the server block.
Source: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var
Demi Magus answer worked for me until Rails 5.
On Apache2/Passenger/Ruby (2.4)/Rails (5.1.6), I had to put
export SECRET_KEY_BASE=GENERATED_CODE
from Demi Magus answer in /etc/apache2/envvars, cause /etc/profile seems to be ignored.
Source: https://www.phusionpassenger.com/library/indepth/environment_variables.html#apache
In my case, the problem was that config/master.key was not in version control, and I had created the project on a different computer.
The default .gitignore that Rails creates excludes this file. Since it's impossible to deploy without having this file, it needs to be in version control, in order to be able to deploy from any team member's computer.
Solution: remove the config/master.key line from .gitignore, commit the file from the computer where the project was created, and now you can git pull on the other computer and deploy from it.
People are saying not to commit some of these files to version control, without offering an alternative solution. As long as you're not working on an open source project, I see no reason not to commit everything that's required to run the project, including credentials.
I had the same problem after I used the .gitignore file from https://github.com/github/gitignore/blob/master/Rails.gitignore
Everything worked out fine after I commented the following lines in the .gitignore file.
config/initializers/secret_token.rb
config/secrets.yml

Resources