为什么我在nginx下使用Passenger获得了Sinatra的404错误?

时间:2011-05-26 22:22:10

标签: ruby nginx sinatra passenger

我有一个基于Sinatra的应用程序在本地运行良好。

我将它移动到带有Passenger的基于nginx的服务器,现在我所有的应用程序/public中的文件链接都返回404错误。主应用程序运行,能够访问/view中正确呈现的HAML模板。文件存在且权限正确;我可以打开并编辑它们,所以我知道它们就在那里。

在我的HAML模板中,我指的是我无法访问的文件:

%script{ :src => 'js/jquery.js' }
%link{ "rel" => "stylesheet", "href" => "styles/input.css" }

当我试图找到问题时,我的config.ru经历了很多突变。目前我有:

require 'sinatra'
require './peering_template.rb'

root_dir = File.dirname(__FILE__)

# disable :run
# set :root, root_dir
# set :views, File.join(File.dirname(__FILE__), 'views')
# set :environment, (ENV['RACK_ENV'] ? ENV['RACK_ENV'].to_sym : :development)

run Sinatra::Application 

该应用程序存在于/home/apps/peering_template

网站空间为/home/webapps

/home/webapps中有一个软链接,如下所示:peering_template -> /home/apps/peering_template/public/

/home/webapps/
`-- peering_template -> /home/apps/peering_template/public/

此配置的nginx.conf的相关部分是:

server {
    listen      3000;
    server_name my_servers_name;
    root        /home/webapps;

    passenger_enabled  on;
    passenger_base_uri /peering_template;
}

显然,我的服务器名称不同。

来自nginx'error.log的相关部分是这样的:

"/home/webapps/js/jquery.js" failed (2: No such file or directory), request: "GET /js/jquery.js HTTP/1.1"

尽我所知,这符合“nginx and passenger configuration using sub-URIs”的指示。我错过了什么?


/home/apps/peering_template/
|-- config.ru
|-- lib
|   |-- bgp-config.rb
|   |-- ios-xr-config.rb
|   |-- ipv4_ipv6_grammar.rb
|   `-- ipv4_ipv6_grammar.treetop
|-- nginx.conf
|-- peering_template.rb
|-- public
|   |-- js
|   |   |-- jquery-1.6.min.js
|   |   |-- jquery-ui-1.8.12.custom.zip
|   |   |-- jquery.js -> jquery-1.6.min.js
|   |   `-- scripts.js
|   |-- peering_template_tool.htm
|   `-- styles
|       `-- input.css
|-- spreadsheets
|   |-- Peering Template-AMS-IX.xlsx
|   `-- Peering Template-IOS-XR-ASH1.xlsx
|-- tmp
|   `-- always_restart.txt
`-- views
    |-- index.haml
    `-- output.haml

我不确定这是否重要,但这是在CentOS release 5.3 (Final)主机上,正在运行nginx/1.0.0passenger (3.0.7)

2 个答案:

答案 0 :(得分:4)

在我写的原始问题中:

  

我将它移动到带有Passenger的基于nginx的服务器,现在我的apps / public中的所有文件链接都返回404错误。主应用程序运行,能够访问/ view中的HAML模板,这些模板可以正确呈现。文件存在且权限正确;我可以打开并编辑它们,所以我知道它们就在那里。

这是我的线索。在我通过Passenger docs的第四次传递时,我遇到了一个讨论/public资产错误的部分:

  

第二种强烈推荐的方法是始终使用Rails辅助方法   静态资产的输出标签。这些辅助方法会自动处理   在您部署应用程序的基础URI之前添加。对于图像   有image_tag,JavaScript有javascript_include_tag和CSS   有stylesheet_link_tag。在上面的例子中,你只需删除    HTML标记并将其替换为内联Ruby,如下所示:

所以,这让我为Sinatra寻找类似的助手。我在Sinatra's extensions page找到了:

  

sinatra-url-for构建Sinatra应用程序中操作的绝对路径和完整URL

     

sinatra-static-assets实现了image_tag,stylesheet_link_tag,javascript_script_tag和link_tag帮助器。这些帮助程序为分派给子URI的应用程序构造正确的绝对路径。

这让我搜索Sinatra的文档,因为它引发了记忆,我重新学习Sinatra's built-in "url"方法:

  

生成网址

     

为了生成URL,您应该使用url helper方法,例如,in   HAML:

     

%a {:href => url('/ foo')} foo

     

如果存在,则需要考虑反向代理和机架路由器。

     

此方法也有别名(参见下面的示例)。

通过使用静态资产方法或Sinatra自己的url帮助程序,它解决了问题。

答案 1 :(得分:1)

你的nginx配置中的root应该是公共(或其他)目录,而不是整个rails应用程序的根目录:

root        /home/webapps/public;

现在将所有静态文件放在该目录中,并且Passenger将足够智能从父目录自动解析config.ru Rack up文件,但如果它们通过nginx存在,则从公共目录提供文件。

除了它的价值之外,你不应该只需要你的应用程序ruby文件,以及你的机架文件中的Sinatra init方法。这是我在另一个应用程序中使用的一个:

require 'application'
run Sinatra::Application

另一个小注意事项,最好将/粘贴在引用这些静态文件的任何URL之前,以确保在页面URL结束的任何位置都可以访问它们,例如。 ...:src => '/js/jquery.js'...

编辑:

我认为在服务器上设置应用的方式存在根本问题。在我看来,它看起来应该是这样的:

/app
  whatever.rb
  /public
    ...

nginx配置应指向app/public作为根,public目录不应该是符号链接。

考虑到所有这些,也许根本应该直接设置为/home/apps/peering_template/public