delayed_job not seeing environment variables - ruby-on-rails

The Rails 4 application is deployed to the production server using Capistrano 3. The delayed jobs daemon starts. When a job is created, it does not recognize environment variables set in /etc/profile using ENV (returns nil). Any thoughts?

Moved the environment variables from /etc/profile to /etc/environment and that seemed to have fixed the problem. Maybe that's the way I was supposed to do it in the first place...I'm not a Linux expert.

Related

Environment variables not working in DigitalOcean

I tried to set the environment variables in .bashrc, .profile, .bash_profile, /etc/environment and also in /etc/defaults/nginx but nothing worked. Only /etc/environment was the file who actually responded echo $MY_VAR output but Rails application didn't picked those variables even after nginx and puma restarted along with daemon-reload other files even didn't responded in terminal (because When i do the ssh it renew the LINUX session). I'm using these environment variables in my_app/config folder's files. Can anyone tell a better way to make these variables work.
I'm using Nginx, Puma, Ruby on Rails 5, Capistrano and Ubuntu 18.04. Thanks in advance
If you're open to using the Dotenv gem, I used it recently in combination with keeping my environmental vars in .env (be sure to add it to your .gitignore). The docs for Dotenv explain how to do the setup. In config/application.rb, you need to add Dotenv::Railtie.load followed by YOUR_SECRECT = ENV['YOUR_SECRECT'] and any other vars you have in .env. Supposedly, if you're using Capistrano, you should be able to append .env with other linked_files in config/deploy.rb, but I ended up having to add the .env file manually to the shared dir on my server. Nevertheless, that setup made my environmental variables available to the config/environments/production.rb file.

Rails console won't load environment variables in secrets.yml

I am trying to debug a problem with secrets.yml loading environment variables, by setting some environment variables in development and running rails c to inspect things. When I load Rails.applications.secrets this way, it is not picking up any of the environment variables I have set (namely, SECRET_KEY_BASE)
If I run the application with the same environment variables set, it picks them up fine (I'm using RubyMine to run the application, but running rails c from the terminal)
In my rails console, I can see the environment variable I've set using ENV['SECRET_KEY_BASE'], but it doesn't show up in Rails.application.secrets. Why?
TL;DR: spring stop
It turns out, as has happened so many times when things aren't making any sense, Spring is the culprit! I solved this problem (thanks to a related discussion) by running spring stop and then trying again, after which it worked perfectly!
Apparently Spring was caching the environment, or certain pieces of the Rails application, and neglecting to reload them when the environment variables changed.

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.

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.

controller can not read env variables on the server

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.

Resources