spring
spring copied to clipboard
rails console on production uses spring
I have been using spring since rails 4.1 released and I really like it. Yesterday we found that there's spring processes running on our production servers. We traced down and found that spring was started when we used rails console with command bundle exec rails console production. We don't want it to be used on production.
Regards your comment on this at https://github.com/rails/rails/pull/12958#issuecomment-28915116
It's already handled by the fact that spring is in the development group of the gemfile. So it's not installed on the server. If it's not installed, the binstub just bypasses spring and runs the underlying command.
What we have experienced is different, spring is installed on our production servers even though it's in :development group.
I'm curious, do you expect us to run bundle install with --without development on production servers? We haven't had need for --without development parameter. We have been using only bundle install --deployment so far.
Maybe we should update the documentation for this?
Yes. It is expected that you run bundle install --without development test on production. Could you submit a pull request to update the documentation?
sure. I'll do that
Closing this. Please send a PR when you're ready.
Sorry for the delay. I have created a PR #337
This is too error-prone for just a blurb in the docs. Nobody should end up with sprung processes in production when doing a typical bundle install.
Other possibilities include checking for a ~/.spring file or env var to indicate that we're in a dev environment and expect to get sprung.
I think we could just make spring throw an error (or perhaps warning) if it's booted into the production env, indicating that it should be in the development gemfile group and therefore not installed on production.
Yes, its too easy to mess up the production env as the this currently works
Also, I sometimes run rails c production or rails c staging on my dev machine (which has spring installed) and I would not want these processes to use spring. I would like them to run clean, as in production, reloading config files each time they start.
Spring should listen to the gem groups before loading. Requiring bundle install to be run in a non standard fashion is not a fix in my opinion.
I had to add DISABLE_SPRING=1 to my production environment to fix this which feels more like a hack than a fix.
I've had to temporarily patch bin/rails to get rails console to work on Heroku. Setting DISABLE_SPRING in Heroku ENV has no effect.
#!/usr/bin/env ruby
unless ENV["DISABLE_SPRING"]
begin
spring_bin_path = File.expand_path('../spring', __FILE__)
load spring_bin_path
rescue LoadError => e
raise unless e.message.end_with? spring_bin_path, 'spring/binstub'
end
end
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
Spring should listen to the gem groups before loading. Requiring bundle install to be run in a non standard fashion is not a fix in my opinion. I had to add DISABLE_SPRING=1 to my production environment to fix this which feels more like a hack than a fix.
Absolutely agree. I always installed gems on deployment server with just bundle install, even without --deployment parameter. It is not feels good for me now to know that I must always remember to include thing ugly '--without test development' to bundle install only to prevent one gem from being installed.
Creating some aliases for this command is another hack. Is it really hard to code the feature of checking if the environment is production and prevent spring starting?
I added ENV['RAILS_ENV'] == 'production' condition which works in the case ofRAILS_ENV=production rails c but not in the case of rails c production
#!/usr/bin/env ruby
unless ENV["DISABLE_SPRING"] || ENV['RAILS_ENV'] == 'production'
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
end
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
yes - relying on not having the gem installed is bad form. it's easy to boot a console on a production machine.
Is this still the default behaviour? I lost days before I figured out that spring was running on production and thus my config wouldn't be read.
@jonleighton @jeremy @rafaelfranca How about https://github.com/agis/spring/commit/2b72ca070998b411db66a49780da8ee4fd710319? If that looks good I could submit a PR.
👍
Still a problem even when specifying this in my Dockerfile, the Spring is still loaded:
ENV BUNDLER_WITHOUT development test
RUN setuser app bundle install --jobs 4 --retry 3
Have not idea how to make it go away. The Spring gem is indeed on my development group btw.