passenger/nginx - environment variable passing, or passenger variable passing - ruby-on-rails

We have 2 rails environments with the same code. One is staging, the other production. Both run using the same 'production' rails settings.
But, we'd like to know what environment we are on. I thought I could set an environment variable on the servers and read that out inside of rails, but, while that works from the console it doesn't work when running behind passenger.
in the admin users .profile file I have:
export MC_TEST=true
But the nginx's/passengers running don't seem to be inside that same environment, and that variable is not set.
I thought I could then maybe put something in the nginx.conf to get passed back to the rails environment, but obviously I am not doing that right either!
So - can anyone tell me how to properly do this? Under no circumstances do we want this variable in ruby/rails/app code.

If you are using nginx with passenger (i.e passenger included in nginx installation), the configuration is as follows:
server {
server_name www.foo.com;
root /webapps/foo/public;
passenger_enabled on;
passenger_env_var DATABASE_USERNAME foo_db;
passenger_env_var DATABASE_PASSWORD secret;
}
https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var

Try passenger_set_cgi_param MC_TEST true in your nginx configuration
passenger_set_cgi_param docs

Related

Elastic Beanstalk, Rails 5, and Passenger: Rails.env frustration

I have a stack in Elastic Beanstalk running the "Passenger with Ruby 2.5 running on 64bit Amazon Linux/2.8.3" image. Rails is v5.2.1. The desire is to make it a staging environment i.e., have 'Rails.env' return 'staging' and run off of a staging.rb configuration. The problem is, it seems to be running as 'production' no matter what I do.
I set up RACK_ENV and RAILS_ENV as EB configuration variables, both set to 'staging'. I confirmed their existence on the server with 'printenv' as ec2-user, webapp, and root.
I tried changing passenger_app_env in the Passenger config to 'staging'. I've confirmed that Passenger Standalone is using the correct config by looking at the process with 'ps aux | grep passenger'.
I've tried switching to the root server and manually doing '/etc/init.d/passenger stop' and then 'start', and the printout confirms Passenger is launching with its 'environment' set to 'staging':
=============== Phusion Passenger Standalone web server started ===============
PID file: /var/app/support/pids/passenger.pid
Log file: /var/app/support/logs/passenger.log
Environment: staging
Accessible via: http://0.0.0.0/
Serving in the background as a daemon.
Problems? Check https://www.phusionpassenger.com/documentation/Users%20guide%20Standalone.html#troubleshooting
I put this into environment.rb and added an EB config var for STAGING to be 'true'.:
if ENV['STAGING']
%w(RACK_ENV RAILS_ENV).each do |key|
ENV[key] = 'staging'
end
end
However, the test page I made in my Rails app still says 'Rails.env' is 'production', and is not using values from 'staging.rb'. And yet, that same test page says that 'ENV['RACK_ENV']' and 'ENV['RAILS_ENV'] are both set to 'staging'.
At this point, I'm out of ideas on how to force the environment in any other way.
After much hacking, I discovered that Passenger was launching with a passenger_app_env of 'production' (its default) and then switching over to 'staging'. Rails.env would get the the
'production' env and use 'production.rb', then RACK_ENV and RAILS_ENV would be overwritten to 'staging', creating the confusing duality.
The solution was moving the passenger_app_env directive higher up in the Passenger Standalone template that Passenger uses; we had it inside of a server directive inside of an http directive. Moving it up out of the server directive and into the http directive itself solved the issue.

Rails on Webfaction (Passenger and Nginx)

This is my first time deploying a Rails app to a production server, I have already done almost everything. I'm stuck with the process to make the app run in production mode, I already typed
$ export RAILS_ENV=production
and
$ echo $RAILS_ENV
and the terminal throws that I am in the production mode, but when I go to a url in my app not yet defined by me, the server is still debugging the templates, I just want the server throws the default 404 page.
Be patient to me I'm new in this. :)
You need to change the rails_env setting in nginx/conf/nginx.conf, as follows:
server {
listen <port_number>;
passenger_enabled on;
root /home/<username>/webapps/<app_name>/<app>/public;
server_name localhost;
rails_env production;
}
If you do this and are greeted with a "502 Bad Gateway" error for your efforts, the issue may be that you don't have the SECRET_KEY_BASE environment variable set. You can generate a suitable value with rake secret, and then add export SECRET_KEY_BASE="<secret>" wherever you're setting other environment variables.
Webfaction's Rails deployment documentation has improved substantially, but this is one of a number of non-intuitive steps it still skips over.

How to make unicorn run a Rails 3.0 app under a path?

I'm migrating from Passenger to Unicorn, and with Passenger I used to run my Rails 3.0 app with the RailsBaseURI option to prefix all URLs with '/blah' for example.
When running the same app under Unicorn, I pass '--path /blah' to unicorn_rails, but the server still serves things as http://server:3000/etc/etc, instead of http://server:3000/blah/etc/etc - I see some assets being requested via /blah/ (like JS files, and so on), but the various links still do not have '/blah/' before them.
So - to summarise - how to I get Unicorn to mount my app under /blah, so that all requests work with '/blah' prepended to the path and all links and assets are created with '/blah/' prepended to them?
Thanks
Here's what I've discovered:
To get a Rails app to serve asset and link URLs, you have to set an environment variable before it starts:
ENV['RAILS_RELATIVE_URL_ROOT'] = '/prefix'
Then, as #d11wtq said, to get the Rack-compatible server (in this case, Unicorn) to actually serve the app under a prefix, you have to, in your config.ru file, instead of the usual run line, do the following:
run Rack::URLMap.new(
ENV['RAILS_RELATIVE_URL_ROOT'] => Rails.application
)
I believe putting something like this in your config.ru should do it:
require ::File.expand_path('../config/environment', __FILE__)
run Rack::URLMap.new(
"/blah" => Rails.application
)
untested
The easy and reliable solution is to set the prefix in your front-end setup.
With passenger+nginx for example, you could use something like this:
server {
listen 80;
server_name www.phusion.nl;
root /websites/phusion;
passenger_enabled on;
passenger_base_uri /prefix;
}
Nothing to change in the source code, one line setup.
But you said you're using unicorn, which front-end are you using ?
Using nginx is should be possible with something like this:
location /prefix {
rewrite ^/prefix/(.*) /$1 break;
proxy_pass http://localhost:8000;
}

phusion passenger not seeing environment variables?

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;

"502 Bad Gateway" with passenger

I am using rails(2.3.10)/passenger(2.2.15)/nginx(0.7.67) , when i run my application, it give me "502 Bad Gateway" and without any production log, my conf file is :
1 server {
2 listen 80;
3 server_name www.why.bz;
4 root /usr/local/apps/why/pro/public;
5 access_log /usr/local/apps/why/pro/log/access.log;
6 passenger_enabled on;
7 }
who can give me some tips, thanks!
I've done Rails deployments full-time for the last couple of years, so hopefully I can help. You've probably figured this problem out by now, but here are some questions to think about for next time:
Since this is a Ruby on Rails application, can you tell where the error is coming from: Nginx or Rails itself? That sounds more like a Nginx issue, but it would be good to know. A quicky peek into the Rails production.log or Nginx's error_log should elucidate this info.
How are you connecting to the application: web browser or command line? Is the IP and hostname set correctly (try the Linux "dig" command to verify)? Are you trying to hit http://localhost:80 ?
There are error log commands that nginx takes that could be configured to help you debug the issue (much like the access_log line): http://wiki.nginx.org/CoreModule#error_log
Lastly, verify the permissions that are set on your web files: The nginx web server needs to be able to access them. At least "read" permissions are needed.
Good luck,
Harmon
change it to
listen 443;
it could be as simple as that.
It could be that your secret key base is missing for the required stage.
One thing that I sometimes forget, especially if I don't start with a staging environment and then add it later, is to add the following to my secrets.yml file:
staging:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
This is telling Rails to get the secret_key_base value from the environment variable, SECRET_KEY_BASE. You must specify this variable by placing this in your nginx configuration:
passenger_env_var SECRET_KEY_BASE yoursupersecretkeybase;
If you don't have a SECRET_KEY_BASE, you can generate one with:
bundle exec rake secret

Resources