Mongohq and heroku setup - ruby-on-rails

I am trying to use MongoHQ with my rails app which uses mongoid. I want to host the app at heroku. From the guide on heroku website, I should add this to my mongoid.yml:
production:
sessions:
default:
uri: <%= ENV['MONGOHQ_URL'] %>
options:
skip_version_check: true
safe: true
My question is, do I have to replace <%= ENV['MONGOHQ_URL'] %> with the URI of the following format:
MONGOHQ_URL: mongodb://<user>:<pass>#hatch.mongohq.com:10034/app003132345
I try replacing it and not replacing it. Either way, I got this error in the log (plus a bunch more, but I suspect this one).
MOPED: Could not resolve IP address for <myusername>
Are there anything else besides, adding this to mongoid.yml and add add-on for mongoHQ in heroku?

<%= ENV['MONGOHQ_URL'] %> is calling a value from the environment. If this were on your local machine you would have to enter the url in your environment.
However, Heroku is awesome and handles this for you! So all you need to do is use that code in your mongoid.yml. If you need to get the url to run your rails app in production on your local machine you can perform
heroku config --app your-app-here
This will print out all of the variables in your heroku environment for this app, including 'MONGOHQ_URL'. You can then copy this url (which will have the user and password filled out, so be careful about security!), and put it in your local environment by typing
export MONGOHQ_URL = url_from_heroku
This will keep the variable until you close your terminal session. However you can always have that variable defined if you add that line to your ~/.bash_rc file (or whatever your bash profile is)
Hope this helps!

Related

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

Step by Step explanation for using Rails secrets.yml without exposing keys to public repo when deploying to Heroku

I am using Rails 4.1.1 and ruby 2.0.0
I've currently ignored my secrets.yml file to my gitignore for github.
secrets.yml
development:
secret_key_base: numb3r57ndl3tt3r5
test:
secret_key_base: differentnumbersandletters13531515
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE'] %>
If this production key is dynamic, where does it read it from? Where do we provide that info? How does that info get to heroku without getting to github?
I already have a secret key environment variable in my heroku app's settings.
I think it was created when I used the heroku_secrets gem https://github.com/alexpeattie/heroku_secrets to run the rake comment rake heroku:secrets RAILS_ENV=production
Can someone explain the conceptual steps, as well as the practical steps on how to utilize secrets.yml properly without exposing secret keys to the public?
If you can also go over with adding another secret key for a different API for instance, that would be much appreciated as well.
I'd like to understand what is happening in the steps in the explanation, rather than something like "do this, do this, do this". Also, if there is code, please specify which file it should be put in, instead of just giving the code, and assuming the reader will know where it goes just based on the code alone (stern look at heroku guide writers)
Thanks! =]
If you use this key <%= ENV["SECRET_KEY_BASE'] %>
On your local machine you can set environment vars in your shell, like (bash or zsh)
export SECRET_KEY_BASE="yourkeybasehere"
And simulate that you run on production (but at your local machine) like
RAILS_ENV=production rails s
However, deploying on Heroku, you can use what they call config vars, by running heroku config:set command for your app.
heroku config:set SECRET_KEY_BASE=yourkeybasehere
Then the Rails app will populate this config var into secret.yml
production:
secret_key_base: yourkeybasehere
Hope this explains thing you need to understand.
Though, if you would like to play and test.
One option is trying to edit your app/views/layouts/application.html.erb file and put the config var you want to display, for instance USERNAME config var
<!DOCTYPE html>
<html>
<head>
<title><%= ENV['USERNAME'] %></title>
</head>
<body>
<%= yield %>
</body>
</html>
Then deploy to heroku and run
heroku config:set USERNAME=gwho
You should see 'gwho' at the page title.
More details about Heroku config vars: https://devcenter.heroku.com/articles/config-vars
More details about Rails 4.1 secrets.yml: http://edgeguides.rubyonrails.org/4_1_release_notes.html#config/secrets.yml
Here's a (hopefully simple) step by step guide FOR HEROKU that should be performed prior to pushing files (secrets.yml) to GitHub, or another host.
*I am not an expert on this topic but this worked well for me and seems like a good solution. It combines info from answers to this question as well as answers to this question (How do you keep secrets.yml secret in rails?) to provide a simple guide :)
1) Copy secrets.yml to another file named secrets_backup.yml
you should now have two files with the same content as secrets.yml
2) Add secrets_backup.yml to your .gitignore
3) Change the text in secrets.yml to the following
development:
secret_key_base: <%= ENV["SECRET_KEY_BASE_DEV"] %>
test:
secret_key_base: <%= ENV["SECRET_KEY_BASE_TEST"] %>
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
4) cd to your rails project folder on the command line
5) In the terminal type heroku config:set SECRET_KEY_BASE_TEST=<pasted key>,
where <pasted key> should be copied and pasted from the test: secret_key_base:<key> which is in secrets_backup.yml
6) In the terminal type heroku config:set SECRET_KEY_BASE_DEV=<pasted key>,
where <pasted key> should be copied and pasted from the development: secret_key_base:<key> which is in secrets_backup.yml
7) My secrets.yml file already had the SECRET_KEY_BASE instead of the actual key, so I suspect yours will too. But if not, set the SECRET_KEY_BASE variable as the other two were set above.
8) Push your repo to GitHub and Heroku
9) Smile because you're the G.O.A.T and show off your sweet website!

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.

Securely providing the database password in a Rails app

As you know, you MUST provide the correct database name, username, and password for the database in the config/database.yml file, or your Rails app will refuse to work.
In the default setup, your password is in plain text in the config/database.yml file. If your app is on a free GitHub repository, then your password is public information. This is not a viable option for a serious app. (It's OK for a tutorial exercise, provided that you don't use this password for anything else.)
I have a solution that has worked for me so far, but I'm wondering if there is something better. You can see my deployed example at https://github.com/jhsu802701/bsf .
What I do is set up the config/database.yml file to provide the username and password for the development environment programatically. For the development environment, I add commands to the config/database.yml script to acquire the development environment username (which is my regular username for the Debian Linux setup I use) and a blank password. (I give my username Postgres superuser privileges.) For the production environment, I add a command in the deployment script that acquires the username and password from files elsewhere on my account and writes this information to the config/database.yml file.
Is there a better solution?
Is there a Ruby gem that covers this? If not, I'm thinking of creating one.
The way that heroku does it, and a vast majority of other rails shops are with ENV variables
Export two variables to your environment,
export POSTGRES_USERNAME='username'
export POSTGRES_PASSWORD='password'
then in your database.yml file you can do
username: <%= ENV['POSTGRES_USERNAME'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
This is how I make it work:
On terminal/cmd:
heroku config:set YOUR_DATABASE_PASSWORD=passywordy
Then, in /config/database.yml file;
production:
<<: *default
password: <%= ENV['YOUR_DATABASE_PASSWORD'] %>
(this password area is automatically generated when I used rails new my_app -d postgresql)
On other than heroku export you variables to system environment (linux) by typing in bash
export KEY=value
Then you can call it in Rails by ENV['KEY']
e.g.
in bash:
export CMS_DATABASE_PASSWORD=MySecurePassword
in secrets.yml:
password: <%= ENV['CMS_DATABASE_PASSWORD'] %>
Setting the environment variables as described in existing posts above, will only persist the environment variables for the duration of the current shell session.
To set the environment variables permanently, the export instruction(s) should be added to your shell config file. (Then run source ~/.bashrc to apply the changes to your current session)
TL;DR: If you're using BASH, add the export instruction(s) to ~/.bashrc.
While the above should suffice (if using BASH on most popular Linux distros), confidently identifying which config file to update for your shell can be quite tricky. The following post explains the reasons why and provides guidance on which config file to edit.
https://unix.stackexchange.com/questions/117467/how-to-permanently-set-environmental-variables

rails 3: is there a way to put a gem's config params in environment.rb instead of foo.yml?

My rails app uses a gem that requires some config params to be specified in foo.yml:
development:
username: MyDevUserName
password: MyDevPassword
production:
username: MyPRODUserName
password: MyPRODPassword
I dont want the password in my source code and want to do something like:
development:
username: <%= ENV['THE_USERNAME'] %>
password: <%= ENV['THE_PASSWORD'] %>
production:
username: <%= ENV['THE_USERNAME'] %>
password: <%= ENV['THE_PASSWORD'] %>
However, for some reason that <%= ENV['XXX'] %> does work in my Settings.yml file, but does not work in my foo.yml file (I'm guessing however the foo gem loads the .yml file it does not allow interpretation).
So...
I'm wondering if Ruby/Rails has a general-purpose way to specify the variables in environment.rb instead of a foo.yml file?
Can i for example have an empty foo.yml file and add the following to environment.rb:
Foo::_something_._somethingelse =
{
:username => ENV['THE_USERNAME'],
:password => ENV['THE_PASSWORD']
}
EDIT: Since you are on Heroku...
Heroku is a different story. Your use of ENV may be conflicting with some functionality built into Heroku for handling config vars such as the ones you are working with. You need (drumroll, please)... CONFIG VARS. See this page in the Heroku Dev Center for information on how to set config vars in your Heroku deployment, how to access them from your app, and how to make it all work locally as well.
EDIT: Below is the original answer, still applicable in the general (non-heroku) case
Even if you put it in environment.rb, it will still be in your source code.
The correct way to do this is to ignore the foo.yml file in your version control (for instance, in git you would add the file to the .gitignore file). That way, you have the file locally where you need it, but it never gets committed to your repository, so your creds aren't exposed. On your deployment server, you will have to manually create that file as well, since when you deploy from source code the deployment won't have it.
If you are using capistrano for deployment, a common approach would be to put the file in [app]/shared/config/foo.yml, then add a deployment task to softlink from [sharedpath] into [releasepath]. Such a task in capistrano might look like this:
task :after_update_code do
run "ln -s #{shared_path}/config/foo.yml #{release_path}/config/foo.yml"
end

Resources