为什么我在 nginx 下使用 Sinatra with Passenger 会出现 404 错误?
我有一个基于 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.0
和 passenger (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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在原来的问题中我写道:
这就是我的线索。在我第四次浏览乘客文档时,我遇到了讨论
/public
资产错误的部分:因此,这让我开始为 Sinatra 寻找类似的帮助程序。我在 Sinatra 的扩展页面中发现:
这让我搜索了 Sinatra 的文档,因为它激发了我的记忆,我重新学习了 Sinatra 的内置 " url”方法:
通过使用静态资产方法或 Sinatra 自己的 url 帮助器解决了这个问题。
In the original question I wrote:
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:So, that got me searching for similar helpers for Sinatra. I found in Sinatra's extensions page:
And that got me searching Sinatra's docs because it sparked a memory, and I relearned Sinatra's built-in "url" method:
By using the static asset methods, or Sinatra's own url helper it fixed the problem.
nginx 配置中的根目录应该是公共(或其他)目录,而不是整个 Rails 应用程序的根目录:
现在将所有静态文件放入该目录中,Passenger 将足够智能来解析配置。 ru 自动从父目录中获取文件,但如果公共目录中的文件存在,则通过 nginx 提供这些文件。
就其价值而言,除了应用程序 ruby 文件的要求以及机架文件中的 Sinatra init 方法之外,您不需要任何其他东西。这是我在另一个应用程序中使用的:
另一个小注意事项,最佳实践是在引用这些静态文件的任何 URL 前面粘贴
/
,以确保无论页面 URL 结束在哪里都可以访问它们,例如。 <代码>...:src => '/js/jquery.js'...编辑:
我认为您的应用程序在服务器上的设置方式存在根本问题。在我看来,它应该看起来像这样:
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:
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:
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:
The nginx config should point to
app/public
as the root, and thepublic
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
?