如何在Rails 3中更改默认的Rails服务器?

15

我刚接触Rails,想知道是否有选项可以更改默认的Rails服务器(即webrick),换成其他服务器,比如“puma”或“thin”。我知道可以使用“rails server”命令指定要运行的服务器,但是我希望在不指定服务器名称的情况下使用此命令来运行默认的Rails服务器。是否有一种方法可以将默认的Rails服务器更改为配置文件或类似文件?非常感谢您的帮助!

8个回答

23

根据 James Hebden 的答案:

Puma 添加到 gemfile 中。

# Gemfile
gem 'puma'

安装Bundle

bundle

将其设为默认选项,将此代码粘贴到script/rails中,在require 'rails/commands'之前:

require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler.get(:puma)

所以 script/rails(在 Rails 3.2.12 中)将如下所示:

#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.

APP_PATH = File.expand_path('../../config/application',  __FILE__)
require File.expand_path('../../config/boot',  __FILE__)
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler.get(:puma)
require 'rails/commands'

运行服务器

rails s
=> Booting Puma

1
为了避免在未安装puma gem时出现错误,您可以使用以下代码包装 Rack::Handler::WEBrick = Rack::Handler.get(:puma)begin ... rescue LoadError end - Abe Voelker
重要提示(如上所述):在“require ´rails/commands´”之前插入行。感谢您的解决方案。 - Linus

9

Rack是Rails和Web服务器之间的接口,它有默认的WEBrick和Thin的处理程序。如果您将以下内容放置在Rails项目根目录中的Gemfile中:

gem 'thin'

rails server会自动使用Thin,从3.2rc2开始就是这样。

不幸的是,这仅适用于Thin,因为Rack没有对Unicorn和其他服务器提供内置支持。

对于具有Rack处理程序的服务器(遗憾的是Unicorn不行),您可以进行一些小技巧,以使rails server使用它们。在rails项目根目录下的scripts/rails文件中,在“require 'rails/commands'”之前添加以下内容:

require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler::<name of handler class>

这基本上将WEBrick的处理程序重置为指向所选服务器的处理程序。要了解支持的Rack处理程序,请查看源中的注释:https://github.com/rkh/rack/blob/master/lib/rack/handler.rb

2
应该是需要 rails/commands,而不是 rack/commands。很抱歉,你无法编辑你的贴子,StackOverflow还说:编辑必须至少6个字符;还有其他可以改进的地方吗? :) - denis.peplin
如果thin不存在,这也适用于puma。 - Joshua Pinter

6

我认为Rails只是将提供给Rack的服务器选项传递下去。Rack有以下逻辑来确定要运行哪个服务器:

https://github.com/rack/rack/blob/master/lib/rack/server.rb#L271-L273

def server
  @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
end

第一种情况是当rails server命令传递了一个:server选项。第二种情况是确定默认值。看起来像这样:

https://github.com/rack/rack/blob/master/lib/rack/handler.rb#L46-L59

def self.default(options = {})
  # Guess.
  if ENV.include?("PHP_FCGI_CHILDREN")
    # We already speak FastCGI
    options.delete :File
    options.delete :Port

    Rack::Handler::FastCGI
  elsif ENV.include?("REQUEST_METHOD")
    Rack::Handler::CGI
  else
    pick ['thin', 'puma', 'webrick']
  end
end

Thin和Puma应该被自动选择。备选项是Webrick。当然,其他Web服务器可以覆盖此行为,使它们成为链中的第一个。

如果默认情况下未选择您的Web服务器,则可以猴子补丁default方法以按照您想要的方式工作。当然,这可能会在未来的rack版本中出现问题。


在代码行pick ['thin', 'puma', 'webrick']中到底发生了什么?如果我没记错,pick似乎不是标准库的一部分(如果我错了请纠正),因此这段代码有点脱离上下文。 - Max Wallace

4

Rack现在会查看一个名为RACK_HANDLER的环境变量文件,以查看您是否指定了默认的rack处理程序。如果您正在使用dotenv,则可以将以下行添加到您的.env文件中来设置默认值,或者从命令行指定分配。

`RACK_HANDLER=webrick`

这应该在此拉取请求的基础上正常工作:

https://github.com/rack/rack/pull/590


1.6.0+ https://github.com/rack/rack/blob/e4e4c397e89c026f9c23500cf7fc14ccdb756010/lib/rack/handler.rb#L56 - dwschrashun
对我有用,谢谢。我不想让 Puma 默认加载。 - abhishek77in
抱歉,将内容添加到.env文件中是无效的,需要通过传递shell命令来实现。 - abhishek77in
是的,抱歉。如果Rails从那里读取您的环境变量(就像使用dotenv一样),将其添加到.env中才能起作用。重要的是,无论您如何将其放入其中,它都会读取环境变量。 - dwschrashun

2

如果您的Gemfile中有thin,您需要执行以下操作:

require 'rack/handler'
Rack::Handler::Thin = Rack::Handler.get(:puma)

这对我起作用,尽管我的Gemfile中没有'thin',而是有'puma'。然而,在这个改变之前,Thin一直作为默认服务器启动,并且'Rack::Handler::WEBrick = Rack::Handler.get(:puma)'的方法不起作用。我使用的是Rails 4.2.6。谢谢! - Nic Nilov

2

不要固守使用rails server命令,只需安装所需的gem并将该命令重命名(例如:rails s Puma)为简单的命令,如rs


2
如果你想使用unicorn/thin等,请在gemfile中添加相关gem,例如:gem 'unicorn'gem 'thin'等,然后在命令行运行bundle install。据我所知,添加这些gem之一会通过rails server运行相应的服务器。 更新: 显然,这只适用于Thin或Puma。

当我在Gemfile中添加gem 'thin'时,它可以工作,但是对于gem 'unicorn'来说却不行,因为当我运行rails server命令时,它会启动Webrick而不是unicorn,因此我想知道是否有其他选项。谢谢。 - airin

1
如果你使用bash,请运行:export RACK_HANDLER=webrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接