phusion passenger not seeing environment variables? - ruby-on-rails

We are running ubuntu servers with Nginx + Phusion Passenger for our rails 3.0x apps.
I have an environment variable set in /etc/environment on the test machines:
MC_TEST=true
If I run a console (bundle exec rails c) and output ENV["MC_TEST"] I see 'true'.
But, if I put that same code on a page ( <%= ENV["MC_TEST"] %> ) it doesn't see anything. That variable does not exist.
Which leads me to question:
1 - What is the proper way to get environment variables into passenger with nginx (not apache SetEnv)?
2 - Why does Passenger not have a proper environment?

Passenger fusion v4+ enables reading of environment variables directly from bashrc file. Make sure that bashrc lives in the home folder of the user under which passenger process is executed (in my case, it was ubuntu, for ec2 linux and nginx)
Here is the documentation which goes into details of bashrc

I've the same problem with you when use passenger with nginx and nginx init script on ubuntu.
The reason is that I use sudo service nginx restart(installed by init script) to start up nginx and
it was running by root and the root did not get your login user environment variable.
There are two solutions for this.
One is running nginx manually.
sudo service nginx stop
sudo -E /path/to/your/nginx
one is add env to your nginx init script
export MC_TEST=true
The latter solution is somehow ugly, But it works. And I think the better way is found a configuration to tell the init script to preserve the login user env.

I got another ugly solution.
env_file = '/etc/environment'
if File.exist?(env_file)
text = File.open(env_file).read
text.each_line do |line|
key, val = line.split('=', 2)
ENV[key] = val.strip
end
end

With nginx you can use the variable passenger_env_var to it. See an example below
passenger_env_var GEM_HOME /home/foo/.rbenv/rubygems;
passenger_env_var GEM_PATH /home/foo/.rbenv/rubygems/gems;
So for your case
passenger_env_var MC_TEST true;

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 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.

Phusion passenger-status: what value for passenger_instance_registry_dir?

I've done a new install of nginx 1.6.3 and passenger 5.0.15 on Ubuntu 14.04 from source in order to add tracing components from AppNeta for my ROR 4.2 app on one of my servers. Nginx and passenger are running and serving pages. I am getting the trace data for server monitoring. All seems well,
However, when I run "passenger-status" (as root), I get the following:
ERROR: Phusion Passenger doesn't seem to be running. If you are sure that it is running, then the causes of this problem could be:
You customized the instance registry directory using Apache's PassengerInstanceRegistryDir option, Nginx's passenger_instance_registry_dir option, or Phusion Passenger Standalone's --instance-registry-dir command line argument. If so, please set the environment variable PASSENGER_INSTANCE_REGISTRY_DIR to that directory and run passenger-status again.
The instance directory has been removed by an operating system background service. Please set a different instance registry directory using Apache's PassengerInstanceRegistryDir option, Nginx's passenger_instance_registry_dir option, or Phusion Passenger Standalone's --instance-registry-dir command line argument.
The problem with this is that it seems to be blocking capistrano deploys; this same error is displayed by cap before exiting.
Passenger is running (it's in the ps output and pages are being served). I just need to tell passenger-status where to find the current running instance. (This is from the Design and Architecture documentation.) Therefore, it seems that setting this instance registry directory value is the required step. But to what value?
According to the Nginx Reference, the defaults are /tmp and /var/run/passenger-instreg And I've found an instance directory in /tmp. So, I've tried setting the PASSENGER_INSTANCE_REGISTRY_DIR to a number of different values:
/tmp
/tmp/passenger.JxmCeiA (the current instance directory, but this changes with each startup of Nginx)
I've even tried creating a directory at /run/passenger, setting that value in the nginx configuration file and restarting nginx. The temporary directory is being created, but passenger-status still gives the same message. Even if I use the /opt/passenger-5.0.15/bin/passenger-status script to make sure I'm using the latest version of that script.
There are some configuration values in the original 'location.ini' directory for passenger, but none were the instance registry directory, so there was nothing to reuse.
Interestingly, the /opt/passenger-5.0.15/lib/phusion_passenger/nginx/config_options.rb file does not have an entry for passenger_instance_registory_dir. It has other nginx configuration options, I would have expected it to have this one as well.
I've tried setting the environment variable as well as the Nginx passenger_instance_registry_dir option, but I must be missing something in my understanding because I can't seem to connect the passenger-status command with the current running instance.
Any help would be greatly appreciated.
Passenger author here.
/tmp/passenger.JxmCeiA is an example of an instance directory. This changes indeed with every startup (because it is specific to an instance).
The parent directory (the directory in which instance directories are located) is the instance registry directory. So in your case, the instance registry directory that is being used is /tmp.
I'm guessing that you have some kind of Passenger installation version mismatch. We've changed the structure of the instance directory a few times in the past, and every time we did this we bump an internal version number to indicate that it's incompatible with previous Passenger versions. Can you double check the following?
Does Passenger appear to be otherwise running correctly?
What Passenger version is compiled inside Nginx?
What is your passenger_root set to? Does it match the Passenger version compiled inside Nginx?
Where is the full path to the first passenger-status in PATH? Does it match passenger_root?
You also seem to be mixing the Phusion Passenger APT repository with source tarball install. Having multiple installations around is generally a bad idea. Try cleaning up your other installs so that you only end up with one.
Also check whether you are setting the PASSENGER_INSTANCE_REGISTRY_DIR environment variable correctly. Note that sudo nukes environment variables, so you need to run passenger-status like this:
# Correct:
sudo env PASSENGER_INSTANCE_REGISTRY_DIR=/tmp passenger-status
# Incorrect, sudo nukes environment variables
export PASSENGER_INSTANCE_REGISTRY_DIR=/tmp
sudo passenger-status
Regarding lib/phusion_passenger/nginx/config_options.rb: that file mainly lists per-server and per-location config options. Many config options in the main context are either not yet ported to the config_options.rb system, or not possible because they require custom attention. At present, passenger_instance_registry_dir is implemented in ext/common/nginx/Configuration.c. As we continue to cleanup and refactor the codebase, this option may eventually be moved to config_options.rb.
In case anyone else is having this problem when starting Passenger using a systemd service, this might be due to systemd's private /tmp. The problem was solved by adding PrivateTmp=false to the service file.
Source
step one check phusion passenger is installed correctly
sudo passenger-config validate-install
"if you see an ouput saying, 'Everything is looks good :-)'" then you are fine, if not you need to reinstall phusion passenger, refer to https://www.phusionpassenger.com/library/walkthroughs/start/
step two check the phusion passenger memory status
sudo passenger-memory-stats
"if you see processes running, then that's good, if not you either have to start some passenger app, or install nginx or apache with extra library for them. For nginx you need nginx and the nginx-extras".
step three uncomment the passenger_root in the nginx.conf file (for ubuntu it's usually /etc/nginx/nginx.conf) or the apache.conf file
restart nginx or apache
sudo service nginx restart # (or systemctl restart nginx, for new version of linux such as ubuntu 15.04, CentOS7)
now you can run
passenger-status
the error should go away now. The mostly likely output you will get is saying "Phusion Passenger is currently not serving any applications."
I'm running Passenger in Nginx integration mode, on Ubuntu 20.04 and I've installed it via apt from the official repos.
What worked for me was adding this to /etc/nginx/conf.d/mod-http-passenger.conf :
passenger_instance_registry_dir /tmp;
Restarting passenger the Capistrano way from the command line should now work:
$ passenger-config restart-app <your_app's_root_path> --ignore-app-not-running
If this works, Capistrano deployments should now work again.

Phusion Passenger 4 & nginx cannot see environment variables in Ubuntu Linux

According to the documentation at https://www.phusionpassenger.com/documentation/Users%20guide%20Nginx.html#env_vars_passenger_apps 15.3.5 Phusion Passenger should be reading environmental variables from .bashrc. I am trying to run a rails 4.2 application from a user account named rails using nginx and Phusion passenger and get a 502 bad gateway error when I try to load it in the browser. The process operates under the correct user. When I open a ruby console in the rails app directory I see the environment variables from my bashrc including secret_key_base. However when I tail my nginx log the error I get is that it is not able to find secret_key_base. I have tried adding this elsewhere including /etc/bash.bashrc and /etc/nginx.conf.
I have found the answer to this horrible question. The answer is at https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems under the heading "Early Termination in Bash". It turns out that the Ubuntu .bashrc does not run if the shell is not interactive. Phusion Passenger does not run in an interactive shell. Therefore we do not load these environment variables for the Phusion Passenger process.
Mike's comment was on track. If you are using rvm then nginx points to a ruby script that you can put the environment variables in before ruby starts.
passenger_ruby /home/rails/.rvm/gems/ruby-2.2.1#was_i_towed/wrappers/ruby;
Is a line in my nginx.conf file. If I open this wrapper in vi or nano then I can add the EXPORT SECRET= to the top of the file and it works.
Other literature suggests that setting the environment variables in /etc/environment should also work.
This issue should also be rendered moot when upgrading to Phusion Passenger 5 which has a facility for specifying environment variables in nginx.conf.

Setting environment variables for Phusion Passenger applications

I've set up Passenger in development (Mac OS X) and it works flawlessly. The only problem came later: now I have a custom GEM_HOME path and ImageMagick binaries installed in "/usr/local". I can put them in one of the shell rc files that get sourced and this solves the environment variables for processes spawned from the console; but what about Passenger? The same application cannot find my gems when run this way.
I know of two solutions. The first (documented here) is essentially the same as manveru's—set the ENV variable directly in your code.
The second is to create a wrapper around the Ruby interpreter that Passenger uses, and is documented here (look for passenger_with_ruby). The gist is that you create (and point PassengerRuby in your Apache config to) /usr/bin/ruby_with_env, an executable file consisting of:
#!/bin/bash
export ENV_VAR=value
/usr/bin/ruby $*
Both work; the former approach is a little less hackish, I think.
Before you do any requires (especially before requiring rubygems) you can do:
ENV['GEM_HOME'] = '/foo'
This will change the environment variable inside this process.
I found out that if you have root priviledges on computer then you can set necessary environment variables in "envvars" file and apachectl will execute this file before starting Apache.
envvars typically is located in the same directory where apachectl is located - on Mac OS X it is located in /usr/sbin. If you cannot find it then look in the source of apachectl script.
After changing envvars file restart Apache with "apachectl -k restart".
I've run into this issue as well. It appears that Passenger doesn't passthrough values set using the SetEnv apache directive - which is unfortunate.
Perhaps it might be possible to set environment variables in your environment.rb or boot.rb (assuming you're talking about a Rails app; I'm not familiar with Rack but presumably it has similar functionality)

Resources