capistrano environment variables are not used in rails code - ruby-on-rails

I am using capistrano to deploy a rails application. To set up email using sendgrid I need to setup environment variables.
I have used
set :default_environment, {
'SENDGRID_USERNAME' => "username",
'SENDGRID_PASSWORD' => 'password',
}
checking with
cap shell
cap > printenv
I can see the environment variables being set correctly.
However the app running through unicorn cannot see these variables, as the sending of email fails with SMTP authentication error.
I have also tried to source a file containing the exports using capistrano
run . app/shared/config/env
But environment variables are still not set
The development environment works fine, so I know the smtp credentials are ok.
How to set environment variables correctly so that the app can see them?

I don't know how to do it using Capistrano, but you can try Figaro gem.

Related

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

How to access environment variables during Capistrano deploy?

I have my rails (4.2) app running through Passenger (5.0.28) + Apache (2.4.7) on an Ubuntu (14.02) system, ruby (2.3.0) managed with rbenv . I deploy with Capistrano (3.4.0).
All my environment variables are set in a very simple profile.d script.
#!/bin/sh
export VAR1=VAL1
export VAR2=VAL2
This works like a charm. My app ENV has all the correct variables, Secrets.yml is properly populated... everything works EXCEPT for when deploying with Capistrano over ssh.
In my deploy.rb I have the following that I think is relavant:
set :ssh_options, {
forward_agent: true,
paranoid: true,
keys: "~/.ssh/id_rsa.pub"
}
Capistrano docs being incredibly limited and ssh\server config not my strong point I can't seem to figure out why my ENV variables aren't seen by Capistrano. If I run puts ENV.inspect during the deploy flow, I get things such as "TERM_PROGRAM"=>"Apple_Terminal" and my local machine user info and whatnot. Why isn't Capistrano using the remote environment? How can I amend my configuration either server side or in my deploy script to fix this?
Thanks for the help.
First I think some clarification of terminology and Capistrano's execution model is needed.
Capistrano is a program that runs on your local machine. So ENV within Capistrano sees your local environment, not the server's. There is no way for Capistrano to "see" the remote ENV with plain Ruby code because the Ruby code that makes up Capistrano is not executing there.
What Capistrano does do is use SSH to send commands to the server to be executed there. Commands like mkdir, bundle install, and so on.
To see this illustrated, add a Capistrano task to your deployment flow that does this:
task :puts_remote_env do
on roles(:all) do
remote_env = capture("env")
puts remote_env
end
end
This will run the env command on the remote server, capture the result, and print it to your console.
I hope this makes it more clear how Capistrano works.
So, as you can see from the puts_remote_env output, the variables defined in your profile.d script are not there. Why?
It is because Capistrano is using a non-login, non-interactive SSH session. In that SSH session, your profile.d script is not being evaluated. This is explained in detail in the Capistrano FAQ: http://capistranorb.com/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/
You need to find another way to set those variables other than profile.d script.
You could specify them in your Capistrano configuration itself (e.g. production.rb) like this:
set :default_env, { var1: "val1", var2: "val2" }
Capistrano will then explicitly set up that environment when it executes SSH commands.
Or you could use a tool like dotenv, which allows Rails to read variables variables from a special file instead of relying on the execution environment.
Or you could experiment with different dot file locations to see if there are some that are still evaluated even in a non-login, non-interactive session. On Ubuntu, I've had success exporting variables at the very top of ~/.bashrc.

Access Environment Variables in production.rb in rails

I want to access the environment variables in production.rb , so I have created a .bashfile & write the variable like export key = value.
I am able to get those variables in rails console but sidekiq is not taking them for sending mails , I am using capistrano for deployment.

How to set up and use Rails environment variables in production server?

I need to set up an environment variable for my rails app. Both in my local machine and in the production server. I read some tutorials on the internet but NONE has given the complete instruction on how to set and use these variable in the actual production server. I use digital ocean and linux server to host my rails app.
I have spent days trying to figure this out, but still haven't found a clear and complete instruction from setting the variables on my local machine -> push it to git repo -> set and use the variables in production server. So, hope somebody can help me here, thanks!
UPDATE:
This is how I currently setup the environment variables in my rails app by using figoro gem:
You can set system-wide environment variables in the /etc/rc.local file (which is executed when the system boots). If your Rails app is the sole user of the Linux system, that is a good place to store credentials such as API keys because there is no risk of including this file in a public Git repository, as it is outside the application directory. The secrets will only be vulnerable if the attacker gains shell access to your Linux server.
Set the environment variables within /etc/rc.local (do not include the <> characters):
export SOME_LOGIN=<username>
export SOME_PASS=<password>
To see the value of an environment variable, use one of the following commands in the Linux shell:
printenv MY_VAR
echo $MY_VAR
To access those environment variables within Rails, use the following syntax:
Inside .rb files or at the rails console
ENV['MY_VAR']
Inside .yml files:
<%= ENV['MY_VAR'] %>
For anyone still having this issue, figaro now has an easy method in setting the production variables in heroku. Just run:
$ figaro heroku:set -e production
ryzalyusoff.
For Unix
You can use LINUX ENV in rails application.
# .env
GITHUB_SECRET_KEY=SECRET
TWITTER_ACCESS_KEY=XXXXXXXXXXXX
# in rails code
puts ENV["TWITTER_ACCESS_KEY"] # => SECRET
Create .env files for local machine and your production server. Export environment variables like this(on server with ssh):
export GITHUB_SECRET_KEY="XXXXXXXXXXXXXXXXXX"
Anyway, storing keys in config - bad idea. Just add .env.example, others keys configs add to .gitignore. Goodluck.
Example with Rails
For Windows
Syntax
SET variable
SET variable=string
SET /A "variable=expression"
SET "variable="
SET /P variable=[promptString]
SET "
Key
variable : A new or existing environment variable name e.g. _num
string : A text string to assign to the variable.
expression : Arithmetic expression
Windows CMD
I believe we should not push a secret file on git.
To ignore such file use gitignore file and push other code on the git.
On the server side just copy the secret file and create a symlink for that file.
You can find demo here http://www.elabs.se/blog/57-handle-secret-credentials-in-ruby-on-rails
You can set your environment variables in production in the same way, you do it for local system. However, there are couple of gems, which make it easier to track and push to production. Have a look at figaro. This will help you in setting up and deployment of env vars.
You can do this with figaro gem
or in rails 4 there is a file named secret.yml in config folder where you can define your environment variables this file is by default in .gitignore file.For production you need to manually copy that file to server for security reason so that your sensitive information is not available to any one
First create your variable like:
MY_ENV_VAR="this is my var"
And then make it global:
export MY_ENV_VAR
You can check if the process succeeded with:
printenv
Or:
echo MY_ENV_VAR

Heroku S3 Env variables

I'm trying to use carrierwave to upload images to S3. It works locally but when I go to deploy to heroku I get the following error:
ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_
access_key
The keys are definitely set because I can see them when I run heroku:config
I've searched every answer I could find on stack and I searched through every answer on the first 3 pages of Google. None of them have worked.
I know the uploading works so it's not the code that's a problem. What settings or variables do I have to set to make this work?
Please help, I can't move forward with my app until this is done (so I can deploy to heroku again without it being stopped because of this error.)
Some info:
Environment Variables
You've got a problem with the calling of your environment variables in
Heroku. ENV vars are basically variables stored in the OS /
environment, which means you've got to set them for each environment
you attempt to your deploy application
heroku config should should the ENV vars you've set. If you don't see ENV['AWS_ACCESS_KEY'] etc, it means you've not set them correctly, which as explained is as simple as calling the command heroku config:add YOUR_ENV_VAR=VAR
Figaro
I wanted to recommend using Figaro for this
This is a gem which basically stores local ENV vars in config/application.yml. This allows you to store ENV variables locally; but more importantly, allows you to sync them with Heroku using this command:
rake figaro:heroku
This will set your env vars on Heroku, allowing you to use them with Carrierwave as recommended in the other answers
It sounds like you have set the ENV variables on Heroku, but you need to hook those up to CarrierWave.
In config/initializers/fog.rb
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS',
:aws_access_key_id => Rails.configuration.s3_access_key_id,
:aws_secret_access_key => Rails.configuration.s3_secret_access_key,
}
end
In your environments/<environment>.rb file
Rails.application.configure do
config.s3_access_key_id = ENV['S3_ACCESS_KEY_ID']
config.s3_secret_access_key = ENV['S3_SECRET_ACCESS_KEY']
end
This sets your Rails config to the ENV variables on Heroku which makes them available as Rails.configuration.<key>

Resources