Unicorn.rb configuration depending on environment - ruby-on-rails

I've got a line in config/unicorn.rb that looks like so:
working_directory "/SomePath/Web\ Development/Rails/learning"
but in the production environment, it needs to be a different path. I want do keep as much as I can under source control (haven't had to give up anything yet). Is there a way to set the working_directory based upon the environment?

How are you trying to access RAILS_ENV or RACK_ENV? It should be through "ENV" like...
ENV['RAILS_ENV']
... or ...
ENV['RACK_ENV']
One or the other should be available when you pass unicorn the "-E" flag (I can't remember which for sure, but I think it's RACK_ENV).

Using unicorn_rails makes the environment variables available.

You can access the rails environment with RAILS_ENV.

Related

Best place to check for env variables in Rails

I use ENV variables for all environments to set up different components of the stack, i.e. Redis, Memcached, etc.
I load all of these in the config/application.rb file, and before that I ensure that all environment variables are present.
I'm running into a problem now where I run a rake task before these variables are set, and so it fails my test. Rake seems to doing it's share correctly. This leads me to believe all of these variables initializations are in the wrong spot.
Now I'm at a loss as to the best place to instantiate all these services or check for their existence.
Init them right after Bundler.require(*Rails.groups) in your application.rb like this https://github.com/bkeepers/dotenv#note-on-load-order
You can check env variables in Rails console, for example:
ENV['YOUR_ENV_VARIABLE']

What does RACK_ENV do in a Rails application?

I have a Rails application already in production. The guy before set these environment variables:
...
export RACK_ENV=none
export RAILS_ENV=production
...
What does RACK_ENV=none do? I can't find documentation on it anywhere. Do I need to set it in the Rails application or can I just delete that export?
IMHO it's useless.
To find the current environment a Rails app first looks for the RAILS_ENV environment variable, then for RACK_ENV environment variable, then it defaults to 'development'.
If you're using version 1.7 or later of the database_cleaner gem, and your CI server has RACK_ENV set to production like mine did, you'll need to set RACK_ENV to none (or anything other than production) to appease database_cleaner's safeguard that your tests aren't running in production. (Or you could disable the safeguard altogether, but that seems less safe.)
Looking at current rack source, it appears that the only value of RACK_ENV that is meaningful to rack is development, which causes rack to default the host to localhost instead of to 0.0.0.0. So it's foolish to set RACK_ENV to production in the first place, or to check that it's been set to that, but that foolishness has taken root all over.

Heroku RACK_ENV remains “production”

I’ve set the environment variable RACK_ENV to staging via heroku_san’s configuration file (as well as manually).
When listing all ENV variables, it shows correctly as being set to "staging". If I check via the console I’m getting a correct result as well.
However, if I log it within my application_controller, it appears to be "production". Any idea why and how to correct this?
RAILS_ENV is set to "production". I’m guessing that this might cause the problem. Can’t these two differ from each other?
Rails looks for RAILS_ENV first, then for RACK_ENV. I guess, Heroku sets RAILS_ENV to production by default and it takes precedence over RACK_ENV. Try to set RAILS_ENV environment variable to "staging" directly.
And if that doesn't work, you should log ENV in your application controller, so that we can see what are all the environment variables from inside.

Detect if application was started as HTTP server or not (rake task, rconsole etc)

I'm using EventMachine and Monetarily to start e TCP server along with my rails application. This is started from config/initializers/momentarily.rb.
My problem is that it starts also when I run rake tasks, like db:migrate. I only want it to start when when I start the HTTP server. Environments won't help, since both the server start and rake tasks are under Development environment. Is there a way of knowing that the application is running the HTTP server as opposed to anything else? Note that is not only rake tasks, the EM starts also if I run the rails console, which is again something not desirable for my case.
unless File.basename($0) == "rake" && ARGV.include?("db:migrate")
# you are not in rake db:migrate
end
There's not a great way of doing this that I know of. You could copy newrelic's approach (check discover_dispatcher in local_environment.rb) which basically has a list of heuristics used to detect if it is running inside passenger, thin, etc.
For passenger it checks
defined?(::PhusionPassenger)
for thin it checks
if defined?(::Thin) && defined?(::Thin::Server)
Set an environment variable in config.ru file, and use it anywhere in the code to detect if it's executed using a rails server command only.
For e.g.
File: config.ru
ENV['server_mode'] = '1'
And using it somewhere as:
File: config/environment.rb
Thread.new { infinite_loop! }.join if ENV['server_mode'] = '1'
Reference: Answer
Maybe you can implement a switch in the initializer based on ARGV?
Something like:
if ARGV.join(' ').match /something/
# your initializer code here
end
Don't start that other server from an initializer. Create a daemon in script/momentarily and start it from within your app.
After your application launches, you could have it shell out to check ps. If ps shows that the HTTP server is running and the running HTTP server has the same pid as your application (check the pid by inspecting $$), then you could launch the TCP server.
In addition to a great answer by Frederick Cheung above, there can be some other "footprints" in actual process environment. Eg. Phusion Passenger adds certain variables to ENV such as:
PASSENGER_APP_ENV
IN_PASSENGER
PASSENGER_SPAWN_WORK_DIR
PASSENGER_USE_FEEDBACK_FD
Web servers typically can also set SERVER_SOFTWARE variable eg.:
SERVER_SOFTWARE=nginx/1.15.8 Phusion_Passenger/6.0.2

How do I force RAILS_ENV=development from within environment.rb or initializers?

Our host does not allow us to modify the passenger config file (i.e. the apache config OR the vhosts file), but we'd like to run rails in dev mode. So we have to specify the environment (prod/dev/test) in one of the files that rails loads AS the application is restarted. Anyone know how to do this?
We've tried the following with no luck:
#environment.rb (before any other code is executed)
`RAILS_ENV=development` # using back ticks
ENV['RAILS_ENV'] = 'development' # assigning to a constant
RAILS_ENV='development' # as suggested by one of the answers, unfortunately does not work.
Setting it right at the top of environment.rb with:
RAILS_ENV = 'development'
should do it. It's possible that passenger overrides this, though.
If you don't have access to the passenger config but you do have access to your virtual hosts then you can also just force it in there with:
RailsEnv development
Why don't you change your production.rb config to match the settings found in development.rb?
In envriornment.rb you could add:
RAILS_ENV="production"
RAILS_ENV.freeze
That way when it tries to get reset later, it will fail.
I'm not sure what other ramifications this will have later or if it will permeate everywhere within rails.
Instead of setting ENV["RAILS_ENV"] in environment.rb, do so in boot.rb.
See here for details.
RAILS_ENV="production"
RAILS_ENV.freeze/ENV
That way when it tries to get reset later, it will fail.
I'm not sure what other ramifications this will have later or if it will permeate everywhere within rails.

Resources