sun*_*nki 7 production ruby-on-rails passenger
我在生产服务器上使用Rails,Passenger(均为3.0.5)和Nginx.当我听说,Rails的应该显示public/404.html或public/500.html代替像开发错误的ActiveRecord::RecordNotFound或Unknown action但这并没有发生.我试图删除config.ru文件并在nginx.conf中设置rack_env或rails_env,但没有任何帮助.
这是我的nginx.conf:
worker_processes 1;
events {
worker_connections 1024;
}
http {
passenger_root /home/makk/.rvm/gems/ruby-1.9.2-p0/gems/passenger-3.0.5;
passenger_ruby /home/makk/.rvm/bin/passenger_ruby;
#passenger_ruby /home/makk/.rvm/wrappers/ruby-1.9.2-p0/ruby;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /home/makk/projects/1server/deploy/current/public;
index index.html index.htm;
passenger_enabled on;
rack_env production;
recursive_error_pages on;
if (-f /home/makk/projects/1server/maintenance.html) {
return 503;
}
error_page 404 /404.html;
error_page 500 502 504 /500.html;
error_page 503 @503;
}
location @503 {
error_page 405 = /maintenance.html;
# Serve static assets if found.
if (-f $request_filename) {
break;
}
rewrite ^(.*)$ /maintenance.html break;
}
location ~ ^(\/phpmyadmin\/)(.*)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(\/phpmyadmin\/)(.*)$;
fastcgi_param SCRIPT_FILENAME /usr/share/phpmyadmin/$fastcgi_path_info;
include fastcgi_params;
}
}
}
Run Code Online (Sandbox Code Playgroud)
看来,这个问题重复这一个,但没有工作的建议.
UPD:我在同一台PC上同时拥有开发和生产应用程序.在生产中config.consider_all_requests_local = false,由于local_request?方法,Rails忽略(在/config/environments/production.rb中).因此下面列出了一种可能的解决方案(取自此处):
# config/initializers/local_request_override.rb
module CustomRescue
def local_request?
return false if Rails.env.production? || Rails.env.staging?
super
end
end
ActionController::Base.class_eval do
include CustomRescue
end
Run Code Online (Sandbox Code Playgroud)
或者对于Rails 3:
class ActionDispatch::Request
def local?
false
end
end
Run Code Online (Sandbox Code Playgroud)
要在Rails 3中使用它,您必须执行以下操作:
首先,创建404和500错误页面.我把我的中app/views/errors/404.html.erb和app/views/errors/500.html.erb.
其次,将以下内容添加到application_controller.rb:
unless Rails.application.config.consider_all_requests_local
rescue_from Exception, :with => :render_error
rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found
rescue_from AbstractController::ActionNotFound, :with => :render_not_found
rescue_from ActionController::RoutingError, :with => :render_not_found
rescue_from ActionController::UnknownController, :with => :render_not_found
rescue_from ActionController::UnknownAction, :with => :render_not_found
end
def render_error exception
Rails.logger.error(exception)
render :template => "/errors/500.haml", :status => 500
end
def render_not_found exception
Rails.logger.error(exception)
render :template => "/errors/404.haml", :status => 404
end
Run Code Online (Sandbox Code Playgroud)
最后,让你的production.rb不考虑所有本地请求:
config.consider_all_requests_local = false
Run Code Online (Sandbox Code Playgroud)
PS:请记住,当发生完整的路由错误时 - 即绝对没有路由匹配,而不仅仅是ActiveRecord NotFound错误,public/404.html将会显示,因此最好将其设置到位.我通常只是将它重定向到我的errors_controller,这可以确保后面提到的任何404错误都没有被正确地重定向到ErrorsController.
<script type="text/javascript">
<!--
window.location = "<%= request.host_with_port %>/errors/404"
//-->
</script>
Run Code Online (Sandbox Code Playgroud)
将root声明移至“服务器”块,以便服务器在收到 5XX、4XX 错误时可以使用 Rails 应用程序定义的错误处理页面。
或者将error_page指令添加到正在使用乘客的位置块,以便错误处理程序可以public/5xx.html在需要时解析 Rails 应用程序公共目录中的 。
如果您的应用程序没有提供页面,并且 nginx 对静态页面不可见,那么它就无法提供您想要的页面。