controller can not read env variables on the server - ruby-on-rails

I used Capistrano 3 to deploy my Rails 4 app to amazon ec2.
Unfortunately, my app on ec2 can not read environment variables.
I've added my variables to ~/.bashrc, /etc/environment and tried
# config/deploy/staging.rb
set :default_env, {
...
}
I can get my variables via $echo $my_var on command line interface and ENV['my_var'] on rails console on my ec2 instance. However, whenever I head to pages that need to read environment variable, I got a http 500 error. According to the log, it seems that my controller can not read the env variable.
I've also rebooted my server and re-deployed many times, but there is no luck.
How can I make my server read the env variable properly?
by the way, I am using unicorn (4.8.3) and the capistrano-unicorn-nginx (~> 3.1.0).

Hopefully you've found a solution for this by now. I'll post a brief answer so maybe it benefits to others that google for this.
Because server environment varies so much from OS to OS, Capistrano wants to ignore it and isolate from it as much as possible. Here's a link with more info. Also, it is probably that capistrano does not load ~/.bashrc, more info here. These are likely the reasons why your app could not read the environment.
I'm not sure why updating the :default_env option was failing. But that's also not the best way to solve this because you'd have to place credentials in a file that is version controlled.
A good way to solve the secret credentials problem is by using either dotenv or rails_config gems. You'll likely prefer the dotenv gem because it works with env vars.
Rails 4.1+, has the built in secrets.yml "feature" which is also fine and will probably be the standard moving forward. I wrote the capistrano-secrets-yml plugin that works with this.

Related

rbenv-vars, environment config file and Paperclip

I have an application running in Ruby on Rails. I use rbenv-vars to manage the environment variables used by the app and some of those variables are used in the environment config file to initialize AWS S3 storage setup in Paperclip's paperclip_defaults hash. However, recently I have updated the value of a S3-related variable in the .rbenv-vars file, restarted the application and Paperclip is always configured with the old (wrong) S3-related variable value. Oddly, the environment variable has the correct value (checked debugging the app and also using rails console) after Ruby environment startup. I temporarily fixed the issue by setting the variable AGAIN in ~/.bash_profile.
Has anyone ever experienced this? Any suggestions are welcome.
I suggest you to used Dot ENV GEM
By using the Gem you can define the ENV variables at system level.
If you are doing any changes related to configuration in rails application. You need to restart your application.

could not get Environment variable in staging server in rails 3 and capistrano 2.15

I am working on rails 3 application . I use capistran 2 for deploying purpose on digital ocean.
Now, I want to store the clients gmail username and password.
I do not want to store it into the code as it is sensitive information.
I want to store it to the server environment variable .
so I make env. variable by following command
export NEW_VAR="Testing export"
I checked it by following command and its saved as env. variable
echo $NEW_VAR
Now I want to access it in my rails application at environment folder in staging.rb and production.rb
I try to use the dotenv gem but it gives me difficulty in getting the env. variable as I am using capistrano 2.
Please help me.
Thanks
Use Figaro gem. Its pretty easy to setup. https://github.com/laserlemon/figaro

Rails app deployed on Centos w/ standalone Passenger and Capistrano can't access ENV variables

I set up a Centos 7 VM using this tutorial (standalone passenger) and RVM. I am deploying the rails app via Capistrano.
https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/standalone/oss/install_language_runtime.html
Everything seems to work, except no matter where I set environment variables, the ENV["myvar"] can't be read in Rails.
I've tried export myvar=test SSHed as the "deployers" as well as root. I've also tried adding it to bashrc. If I login as deployer and do the following:
#symlink to current capistrano deploy
cd ~/rails/railsapp/current/
rails r "puts ENV['myvar']"
It gives me the correct ENV output. However, if I try to output ENV['myvar'] from my actual deployed via capistrano rails app, I get nothing.
Where am I supposed to set these ENV vars? I know the ENV vars in rails are done correctly, because the app deployed to heroku, as well as on my dev machine, correctly output ENV['myvar'].
Generally, your setup should work. Since version 4, a standalone Passenger should inherit all variables defined in the shell startup scripts. There is a nice documentation about environment variables in various scenarios related to using Passenger.
I would check or two things:
That your .bashrc is loaded from .profile. If it weren't, then your variables would be loaded only in an interactive shell but not in passenger, which would explain the behavior your describe when you tried to log in as the deployers. Let me quote from the doc:
Make sure your ~/.bashrc is actually included by your ~/.profile, which might not be the case if you created the user with useradd instead of adduser for example.
Also, take a look at this section of the docs and check that you obey the conditions upon which Passenger actually passes the environment vars to the application.

Missing secret token, secret key base when running my application in production

I work with Rails 4 and Ruby 2.1 and sorry but I am working on Windows
I have read a lot about this topic "Missing secret token, secret key base" but actually I do not understang anything.
I do not use Heroku, Git, Puma, Passenger or everything else I've read. I just thought I could instead of running rails s as usual run rails s -e production and see what is the version of my web application in production.
But I have the error "Missing secret_token and secret_key_base for production environment, set these values in config/secrets.yml"
I read about solutions using openSSL, export SECRET_KEY_BASE=<the long string> but I do understand the solutions.
I thought it was a problem related to the system of connection by password I settled thanks to Rails tutorial of Micheal Hartl. So disabled SSL connection. But nothing change.
This is my config/secrets.yml :
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Can someone explain how to concretely solve this issue ?
GDMN I am sorry that everyone gave you such poor explanations and instructions. Ok onto it then, shall we......
First everyone is right you no longer need "secret_token", you do however need "secret_key_base". What this does is it secures your visitors connection and keeps your system and app more secure. That is a simple explanation but all you need to worry about at the beginners level.
Second the ENV stands for "Environment Variable" they are used in all operating systems and they refer to variables on the OS level that hold information that you do not want to be accessible t someone trying to gain access to your site. For instance in Ruby On Rails if you HARD CODE the secrety_token_base string/hash then I hacker can gain access by using your security_token against you. I have seen this happen and it is not pretty, if the individual is skilled enough then they can gain access to even your root/admin account.
Now on to setting it all up. I only know the linux way and I know you are looking for the windows method but this should at least give you an understanding to seek out the information relevant to your operating system.
First thing you would need to do is generate your secret_token_base by running
bundle exec rake secret
To my knowlege this is the way you do it in all Operating Systems. After you run the above command the console will return a string and you would need to copy it. Once copied you would run the following command:
export SECRET_KEY_BASE=WhatYouJustCopied
Then we would check to make sure the Environment Variable SECRET_KEY_BASE is set by running:
env | grep -E "SECRET_TOKEN|SECRET_KEY_BASE"
If you do not have SECRET_TOKEN set you will only get the KEY_BASE.
If you want to learn more in depth information please visit this link it may be a little dated but most of it is still relevant and conceptually it is the same.
I wish you luck on your new found ROR Adventure! It is fun once you get the hang of it!
From your command prompt, run:
bundle exec rake secret
It will generate a long string of characters. Copy this string and paste it into config/secrets.yml as follows:
production:
secret_key_base: <paste the string here>
Note: only do this if you are not using a public repository. This key should not be accessible to anyone else. An alternate, and more secure way of doing this is using an environment variable. See this: http://daniel.fone.net.nz/blog/2013/05/20/a-better-way-to-manage-the-rails-secret-token/
So, if you look inside the secrets.yml file, you will see where your secret_key_base is set for each of your environments. When you look at the production setting, it wants an env variable to initialize your secret_key_base. Normally, in production, you would want your app server to fetch the value from a general place in case you need to spin multiple servers up, you wouldn't have to hard-code your secret_key_base everywhere since that is not a secure way of setting that variable.
Basically, you will have to have that env variable set up on the machine that will run your rails app in production. There are so many different ways to set this.
What I have set up to initialize my ENV variables for production is have a separate yml file that is constructed like this
# config/env_provider.yml
production:
SECRET_KEY_BASE: "KEY GOES HERE"
other_production_variables: #...etc
Then my separate servers will be told where to find this file before initializing the variables (This is not checked into version control). After the file is in place it will know to initialize the variables from the following code in environment.rb before your app initializes
#config/environment.rb
YAML.load_file("#{::Rails.root}/config/env_provider.yml")[::Rails.env].each {|k,v| ENV[k] = v }
# This is before Rails.application.initialize!
The thing with this set up is to make sure that you do not have this file accessible to everyone to see, only allow your application servers to use it. Anyway, this is how I deal with ENV variables and deploy them to production. I hope this helps you.

Why are my Rails initializers caching ENV variables in the console (Foreman, Dev env)

What started as a minor annoyance has now turned into a headache. I am building a Rails 4 app and am using Foreman for my dev setup with a Procfile and .env file for configuration. When I set an ENV variable in the .env file, it is correctly picked up by my app. In this case I am setting some ENV options for Paperclip in an initializer.
The problem surfaces when I go to change the value of the ENV variables. In the console, if I type ENV["MY_VAR"], it shows the new value. However, the value that was used in my initializer, which presumably was run when I started the console, shows the old value! Nowhere in my project is the old value listed anywhere. This leads me to believe that the environment is being cached somehow or that the env variables are being exported to my shell. I'm running out of places to look so any help would be greatly appreciated! I am developing on a Mac (10.9.4) with Ruby 1.9.3-p374 and Rails 4.1.0.
Example:
ROOT/.env
S3_BUCKET=mybucket
config/initializers/paperclip.rb
Paperclip::Attachment.default_options[:s3_credentials] = {bucket: ENV["S3_BUCKET"]}
If I change the value of S3_BUCKET to "newbucket" and run "foreman run rails c" or "rails c" to enter the console, this is what happens:
ENV["S3_BUCKET"] # => "newbucket"
Paperclip::Attachment.default_options[:s3_credentials] # => {bucket: 'mybucket'}
I should mention that this behavior also occurs in my classes that I've put in /lib. I imagine this is all due to something silly that I've overlooked. Any ideas?
If you're using Rails 4 out of the box, it comes with a gem called Spring that's intended to make your life easier by preloading an instance of your application in the background and reloading it as your code and configuration files change.
Spring, however, only monitors Rails' default configuration files, so you'll need to configure Spring to monitor additional any other files that you wish to trigger a reload.
Spring reads ~/.spring.rb and config/spring.rb for custom settings. You can add add the following line to the file of your choosing to watch your .env file for changes:
Spring.watch '.env'
See Spring's configuration documentation in the README for more info.

Resources