为什么我在 nginx 下使用 Sinatra with Passenger 会出现 404 错误?

发布于 2024-11-10 10:14:46 字数 2428 浏览 3 评论 0原文

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

据我所知,这符合“使用子 URI 的 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

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

I have a Sinatra-based app that runs fine locally.

I moved it to a nginx-based server with Passenger and now all my links to files in my apps /public are returning 404 errors. The primary app runs, is able to access the HAML templates in /view, which render correctly. The files exist and permissions are correct; I can open and edit them so I know they're there.

In my HAML templates I'm referring to the files that I can't access like this:

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

My config.ru has gone through a lot mutations while I try to find the problem. Currently I have:

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 

The app exists in /home/apps/peering_template.

The web space is /home/webapps.

There is a soft-link in /home/webapps like this: peering_template -> /home/apps/peering_template/public/.

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

The pertinent part of nginx.conf for this config is:

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

    passenger_enabled  on;
    passenger_base_uri /peering_template;
}

Obviously, my server's name is different.

The pertinent part from nginx' error.log is like this:

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

As near as I can tell this fits the directions for an "nginx and passenger configuration using sub-URIs". What am I missing?


/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

I'm not sure if it matters but this is on a CentOS release 5.3 (Final) host, running nginx/1.0.0 and passenger (3.0.7).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゞ花落谁相伴 2024-11-17 10:14:46

在原来的问题中我写道:

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

这就是我的线索。在我第四次浏览乘客文档时,我遇到了讨论 /public 资产错误的部分:

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

因此,这让我开始为 Sinatra 寻找类似的帮助程序。我在 Sinatra 的扩展页面中发现:

sinatra-url-for 在 a 中构建操作的绝对路径和完整 URL西纳特拉应用程序

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

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

生成 URL

要生成 URL,您应该使用 url 帮助器方法,例如,
哈姆尔:

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

它会考虑反向代理和机架路由器(如果存在)。

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

通过使用静态资产方法或 Sinatra 自己的 url 帮助器解决了这个问题。

In the original question I wrote:

I moved it to a nginx-based server with Passenger and now all my links to files in my apps /public are returning 404 errors. The primary app runs, is able to access the HAML templates in /view, which render correctly. The files exist and permissions are correct; I can open and edit them so I know they're there.

That was my clue. On my fourth pass or so through the Passenger docs I ran into a section that talked about errors with /public assets:

The second and highly recommended way is to always use Rails helper methods to
output tags for static assets. These helper methods automatically take care of
prepending the base URI that you’ve deployed the application to. For images
there is image_tag, for JavaScript there is javascript_include_tag and for CSS
there is stylesheet_link_tag. In the above example you would simply remove the
HTML tag and replace it with inline Ruby like this:

So, that got me searching for similar helpers for Sinatra. I found in Sinatra's extensions page:

sinatra-url-for construct absolute paths and full URLs to actions in a Sinatra application

sinatra-static-assets implements image_tag, stylesheet_link_tag, javascript_script_tag and link_tag helpers. These helpers construct correct absolute paths for applications dispatched to sub URI.

And that got me searching Sinatra's docs because it sparked a memory, and I relearned Sinatra's built-in "url" method:

Generating URLs

For generating URLs you should use the url helper method, for instance, in
Haml:

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

It takes reverse proxies and Rack routers into account, if present.

This method is also aliased to to (see below for an example).

By using the static asset methods, or Sinatra's own url helper it fixed the problem.

风苍溪 2024-11-17 10:14:46

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

root        /home/webapps/public;

现在将所有静态文件放入该目录中,Passenger 将足够智能来解析配置。 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

The root in your nginx config should be the public (or some other) directory, not the root of the entire rails application:

root        /home/webapps/public;

Now put all your static files inside that directory, and Passenger will be smart enough to resolve the config.ru Rack up file from the parent directory automatically, but serve the files from the public directory if they exist through nginx.

For what it's worth, as well, you shouldn't need anything but the require of your application ruby file, and and the Sinatra init method in your rack file. Here's one I use in another app:

require 'application'
run Sinatra::Application

One other little note, best practice to stick a / in front of any URLs that reference these static files to ensure they're reachable wherever the page URL ends up, eg. ...:src => '/js/jquery.js'...

Edit:

I think there's a fundamental problem with the way your app is setup on the server. In my mind, it should look something like this:

/app
  whatever.rb
  /public
    ...

The nginx config should point to app/public as the root, and the public directory should not be a symlink.

With all that in mind, perhaps the root should just be set directly to /home/apps/peering_template/public?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文