Rails 5.2 application secrets empty at Heroku - heroku

I deployed to Heroku with success but there is an issue with credentials.
I added RAILS_MASTER_KEY env variable at Heroku app CONFIG VARS section and copy-pasted the value from my app master.key file:
Then when I check its value from Heroku console, it is still nil:
Loading production environment (Rails 5.2.3)
irb(main):001:0> Rails.application.secrets.secret_key_base
=> nil
irb(main):002:0> Rails.application.secrets
=> {:secret_key_base=>nil, :secret_token=>nil}
irb(main):003:0>
But when I check it other way:
ENV['RAILS_MASTER_KEY']
=> "sdfghjklm.......1a0befa6139"
it is displayed correctly.
What am I missing?

I figured out myself, - I followed a Pluralsight tutorial on Rails API and it used the old way to get Rails secrets:
Rails.application.secrets.secret_key_base
Starting from Rails 5.2 there is no more secrets.yml file and the right way to get the env variables saved in credential.yml.encis as follows:
Rails.application.credentials.dig(:secret_key_base)
After updating the corresponding code, everything works as needed. Hope this helps.

Changing
SECRET = Rails.application.secrets.secret_key_base
to:
SECRET = ENV['SECRET_KEY_BASE'] || Rails.application.secrets.secret_key_base
worked for me.
ENV['SECRET_KEY_BASE'] worked in production environment while Rails.application.secrets.secret_key_base worked in development environment.

Related

Assets loading issue on Rails 5 app with Heroku

I am facing asset loading issue in Rails 5 application deployed on Heroku.
App Configuration is,
ruby => ‘2.3.1’
rails => '~> 5.0.1'
When image is stored on path,
app/assets/home/image1.jpg
I am accessing it in view as,
= image_tag('/assets/home/image1.jpg’)
which is working properly in Development ENV, but not in Production ENV.
As per Heroku log,
ActionController::RoutingError (No route matches [GET]
"/assets/home/image1.jpg")
If I am moving image directly to
app/assets/image1.jpg
then its working on Production ENV.
Please guide about it.
Thanks
It looks like you assets are not compile on heroku.
Follow below code:
config/environments/production.rb
config.assets.compile = true
then run commands:
RAILS_ENV=production rake assets:precompile
then push all compiled files with menifest file to heroku.

Environment Variables on Heroku and Mailgun Problems with Phoenix Framework

I was following this guide on deploying to Heroku and this one for sending email.
Everything works fine in development. My variables are set in Heroku:
heroku config
...
MAILGUN_DOMAIN: https://api.mailgun.net/v3/xxxxxx.mailgun.org
MAILGUN_KEY: key-3-xxxxxx
...
And loaded from the config files like so:
config :take_two, Mailer,
domain: System.get_env("MAILGUN_DOMAIN"),
key: System.get_env("MAILGUN_KEY")
However when I try to send email on Heroku when the Mailgun config is set from environment variables I get this error:
** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1
(elixir) lib/io.ex:346: IO.chardata_to_string(nil)
(elixir) lib/path.ex:467: Path.join/2
(elixir) lib/path.ex:449: Path.join/1
lib/client.ex:44: Mailgun.Client.send_without_attachments/2
This happens when the domain is not set for the Mailgun Client. But it is supposed to be set from the environment variable. I made a simple module to test:
defmodule TakeTwo.Mailer do
require Logger
use Mailgun.Client,
Application.get_env(:take_two, Mailer)
def blank_shot do
Logger.info Application.get_env(:take_two, Mailer)[:domain]
Logger.info Application.get_env(:take_two, Mailer)[:key]
send_email from: "steve#xxx.com", to: "speggy#xxx.com", subject: "Hello", text: "This is a blank shot"
end
When I run TakeTwo.Mailer.blank_shot I see the correct domain/key variables logged followed by the error. I am not sure how to debug the Mailgun client remotely.
Finally, if I recreate the above module in the shell (after running heroku run iex -S mix) it works just fine!?
I feel like when the original module is being loaded perhaps the environment variables have yet to be loaded??
The answer was a little buried in a comment so I wanted to make it easier to find. As the other answer mentions, the environment variables aren't available, but the buildpack lets you configure them to be:
I created a elixir_buildpack.config file and added the following:
config_vars_to_export=(DATABASE_URL MAILGUN_DOMAIN MAILGUN_KEY SECRET_KEY_BASE)
The environment variables aren't available at build time. I had the same issue and decided to get rid of the macro carrying the configuration. You can use this patch to move on.

Figaro - Rails Missing secret_key_base for development

I've just switched to using the Figaro gem v1.0.0 with Rails 4.1.6.
Since deleting my secrets.yml file I now get the error:
Unexpected error while processing request: Missing secret_key_base for 'development' environment, set this value in config/secrets.yml
Do i still need the secrets.yml file - isn't this the job of Figaro's application.yml file?
My application.yml file is like
development:
secret_key_base: 56....
Looking into the Railties gem at https://github.com/rails/rails/blob/master/railties/lib/rails/application.rb you can see the secrets method defined which includes a fallback for secret_key_base
def secrets #:nodoc:
#secrets ||= begin
secrets = ActiveSupport::OrderedOptions.new
yaml = config.paths["config/secrets"].first
if File.exist?(yaml)
require "erb"
all_secrets = YAML.load(ERB.new(IO.read(yaml)).result) || {}
env_secrets = all_secrets[Rails.env]
secrets.merge!(env_secrets.symbolize_keys) if env_secrets
end
# Fallback to config.secret_key_base if secrets.secret_key_base isn't set
secrets.secret_key_base ||= config.secret_key_base
secrets
end
end
In config/application.rb adding the following resolves the issue
config.secret_key_base = Figaro.env.secret_key_base
I have never used Figaro gem but try these, create the config/secret.yml file and inside write:
development:
secret_key_base: <%= ENV['secret_key_base'] %>
I was just informed that as of Rails 4.1.x, config/secrets.yml does need to be uploaded to heroku. Rails will no longer look directly at its ENV in order to find its secret_key_base.
So secrets.yml needs to come off of the .gitignore file, and your project would need to be recommited and re-pushed to heroku.
(secrets.yml would still get its values from heroku's ENV, which would still be loaded up via Figaro the same way as before - figaro heroku:set -e production. Use heroku config to get a nice quick look at your ENV variables to confirm they are there)

Omniauth authentication fails in Rails 4

I am working in rails 4 and I am trying to authenticate using github. So in my Github application I have this:
URL: http:// localhost:4000
Callback URL: http:// localhost:4000/auth/github/callback
The callback url is the url that Github will try to reach when the authentication is done right?
So why do I get a Github page 404 error when I click on my link:
<%= link_to 'Sign in with Github', '/auth/github' %>
I am working on a localhost development enviroment so that might be the problem?
Also when i type http:// localhost:4000/auth/github/callback on my browser I get an OmniAuth::Strategies::OAuth2::CallbackError
why? I have this in my routes.rb
post 'auth/:provider/callback' => 'home#index'
Is Rails 4 and Omniauth bugged?
(added the space in localhost so stackoverflow accepts my post)
I have github working with the gem omniauth-github
and a file config/initializers/omniauth.rb containing
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
end
However, when I enter http://localhost:3000/auth/github/callback on my browser I also get OmniAuth::Strategies::OAuth2::CallbackError so this shouldn't be the problem.
My config/environment.rb looks like
# Load the rails application
require File.expand_path('../application', __FILE__)
# Load the app's custom environment variables here, so that they are loaded before environments/*.rb
app_environment_variables = File.join(Rails.root, 'config', 'app_environment_variables.rb')
load(app_environment_variables) if File.exists?(app_environment_variables)
...
and my config/app/environment_variables.rb looks like
# OAuth Keys and Secrets
if Rails.env.production?
ENV['GITHUB_KEY'] = 'd1234a3a123a1a3a123c'
ENV['GITHUB_SECRET'] = '1234azer123azer1231209jeunsghezkndaz1234'
else
ENV['GITHUB_KEY'] = 'qsflkjkj685bg554456b'
ENV['GITHUB_SECRET'] = 'qslkfj7757kqfmlsdh675hlfsd587kjfdh687jsd'
end
See Is it possible to set ENV variables for rails development environment in my code? for more details on that.
I have 2 applications registered on github. One app_name-dev with key qsflk..., url http://localhost:3000 and callback url http://localhost:3000/auth/github/callback and one app_name with key d1234a....
Check that you have done that correctly. Maybe try to change localhost to 127.0.0.1.
For me it was Github's new stricter URI matching that was producing a 404 when trying to redirect to http://localhost:3000/auth/github/callback, I solved it by passing the redirect URI as a parameter with Omniauth.
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'],
:scope => 'user,public_repo',
:redirect_uri => ENV['GITHUB_REDIRECT']
end
If your on Linux/Mac you can add environment variables from the command line.
$ export GITHUB_REDIRECT=http://localhost:3000/auth/github/callback
Alternatively, you could use something like Foreman that will let you add a .env file which you can use to store your variables in.
Just remember to add the appropriate redirect URI to your production environment's variables, and you're good, to go.

Heroku logging not working

I've got a rails 3.1 app deployed on Heroku Cedar. I'm having a problem with the logging. The default rails logs are working just fine, but when I do something like:
logger.info "log this message"
In my controller, Heroku doesn't log anything. When I deploy my app I see the heroku message "Injecting rails_log_stdout" so I think calling the logger should work just fine. Puts statements end up in my logs. I've also tried other log levels like logger.error. Nothing works. Has anyone else seen this?
MBHNYC's answer works great, but it makes it difficult to change the log level in different environments without changing the code. You can use this code in your environments/production.rb to honor an environment variable as well as have a reasonable default:
# https://github.com/ryanb/cancan/issues/511
config.logger = Logger.new(STDOUT)
config.logger.level = Logger.const_get((ENV["LOG_LEVEL"] || "INFO").upcase)
Use this command to set a different log level:
heroku config:set LOG_LEVEL=error
I was just having the same issue, solved by using the technique here:
https://github.com/ryanb/cancan/issues/511
Basically, you need to specify the logger outputs to STDOUT, some gems interfere with the logger and seem to hijack the functionality (cancan in my case).
For the click lazy, just put this in environments/production.rb
config.logger = Logger.new(STDOUT)
config.log_level = :info
As of the moment, it looks like heroku injects these two plugins when building the slug:
rails_log_stdout - https://github.com/ddollar/rails_log_stdout
rails3_server_static_assets - https://github.com/pedro/rails3_serve_static_assets
Anything sent to the pre-existing Rails logger will be discarded and will not be visible in logs. Just adding this for completeness for anyone else who ends up here.
The problem, as #MBHNYC correctly addressed, is that your logs are not going to STDOUT.
Instead of configuring manually all that stuff, Heroku provides a gem that does this all for you.
Just put
gem 'rails_12factor', group: :production
in your Gemfile, bundle, and that's it!
NOTE: This works both for Rails 3 and 4.
Source: Rails 4 on Heroku

Resources