为什么在nginx下与Passenger一起使用Sinatra会出现404错误?

问题描述 投票:2回答:2

我有一个基于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"

据我所知,这完全符合“ 使用sub-URIs的nginx和乘客配置 ”的说明。 我想念什么?


/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

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

ruby nginx sinatra passenger
2个回答
4
投票

在最初的问题中,我写道:

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

那是我的线索。 在大约四次通过“ 旅客”文档的过程中,我遇到了讨论/public资产错误的部分:

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

因此,这使我为Sinatra寻找类似的帮助程序。 我在Sinatra的扩展页面中找到了:

sinatra-url-用于构造指向Sinatra应用程序中操作的绝对路径和完整URL

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

这让我搜索Sinatra的文档,因为它引发了记忆,并且我重新学习了Sinatra的内置“ url”方法:

产生网址

为了生成URL,您应该使用URL helper方法,例如在Haml中:

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

如果存在,它将考虑反向代理和Rack路由器。

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

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


1
投票

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

root        /home/webapps/public;

现在将所有静态文件放在该目录中,Passenger会足够聪明,可以自动从父目录解析config.ru机架文件,但是如果它们通过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

© www.soinside.com 2019 - 2024. All rights reserved.