簡體   English   中英

為什么我在 nginx 下使用 Sinatra 時會出現 404 錯誤?

[英]Why am I getting 404 errors with Sinatra with Passenger under nginx?

我有一個在本地運行良好的基於 Sinatra 的應用程序。

我將它移到了基於 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中。

web 空間是/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 和使用子URI 的乘客配置”的指示。 我錯過了什么?


/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)

在最初的問題中,我寫道:

我將它移到了基於 nginx 的服務器上,現在我的應用程序 /public 中的所有文件鏈接都返回 404 錯誤。 主應用程序運行,能夠訪問 /view 中正確呈現的 HAML 模板。 文件存在且權限正確; 我可以打開和編輯它們,所以我知道它們就在那里。

那是我的線索。 在我通過乘客文檔的第四次左右時,我遇到了一個討論/public資產錯誤的部分:

第二種也是強烈推薦的方法是始終對 static 資產的 output 標記使用 Rails 輔助方法。 這些輔助方法會自動處理您已將應用程序部署到的基本 URI。 對於圖像,有 image_tag,對於 JavaScript,有 javascript_include_tag,對於 CSS,有 stylesheet_link_tag。 在上面的示例中,您只需刪除 HTML 標記並將其替換為內聯 Ruby ,如下所示:

所以,這讓我為 Sinatra 尋找類似的助手。 我在Sinatra 的擴展頁面中找到:

sinatra-url-for 為Sinatra 應用程序中的操作構建絕對路徑和完整 URL

sinatra-static-assets實現了 image_tag、stylesheet_link_tag、javascript_script_tag 和 link_tag 助手。 這些助手為分派到子 URI 的應用程序構造正確的絕對路徑。

這讓我搜索了 Sinatra 的文檔,因為它引發了 memory,我重新學習了Sinatra 的內置“url”方法:

生成 URL

要生成 URL,您應該使用 url 輔助方法,例如在 Haml 中:

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

它考慮了反向代理和機架路由器(如果存在)。

此方法也別名為 to(參見下面的示例)。

通過使用 static 資產方法,或 Sinatra 自己的 url 助手,它解決了問題。

nginx 配置中的根目錄應該是公共(或其他)目錄,而不是整個 rails 應用程序的根目錄:

root        /home/webapps/public;

現在將所有 static 文件放在該目錄中,Passenger 將足夠聰明地自動解析父目錄中的config.ru Rack 文件,但如果公共目錄中的文件通過 nginx 存在,則提供這些文件。

對於它的價值,除了你的應用程序 ruby 文件和機架文件中的 Sinatra init 方法之外,你不需要任何東西。 這是我在另一個應用程序中使用的:

require 'application'
run Sinatra::Application

另一個小注意事項,最佳實踐是在引用這些 static 文件的任何 URL 前面加上/ ,以確保在頁面 URL 結束的任何地方都可以訪問它們,例如。 ...:src => '/js/jquery.js'...

編輯:

我認為您的應用在服務器上的設置方式存在根本問題。 在我看來,它應該看起來像這樣:

/app
  whatever.rb
  /public
    ...

nginx 配置應該指向app/public作為根,並且public目錄不應該是符號鏈接。

考慮到所有這些,也許根目錄應該直接設置為/home/apps/peering_template/public

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM