Rails 3.2 资产管道在 Thin 和 Apache 中未找到资产

9
我的问题与这个类似:Rails 3.2 Asset Pipeline with Passenger Endless Errors,但当我尝试实际访问时,出现了无法加载应用程序的错误。
<link href="/assets/application-eed7996ee9017637f923133371ab3e92.css" media="all" rel="stylesheet" type="text/css" />

我得到了一个404错误。 这里有一件我不理解的事情。 它正在寻找/assets/,但是当我查看已部署的代码时,assets仅在/public/assets中,这实际上是指向/var/www/myapp/shared/assets的符号链接。 那么是什么让应用程序知道在/assets中查找会产生正确的结果呢?
我正在使用Rails 3.2.0、ruby-1.9.3-p125,部署到Ubuntu、Apache和Thin。
我需要澄清一下:我的资产确实部署到了服务器上。 一切正常工作正常,直到它们需要被服务,这时production.log告诉我它们正在寻找/assets/application-eed7996ee9017637f923133371ab3e92.css,而这会导致404错误。
对于每个请求,我的thin.log都会说:
cache: [GET /] miss

并且production.log显示

ActionController::RoutingError (No route matches [GET] "/assets/application-abecf2e096af9ee80697fd49e79a55e7.js"):

更新 @Brandan 感谢您的帮助。我的资产确实在 RAILS_ROOT/public/assets 中。我将其添加到了我的 Apache vhost 文件中:

DocumentRoot /var/rails/myappname/current/public

RewriteEngine On
XSendFile On
XSendFilePath /var/rails/myappname #not even sure if this line is needed

<LocationMatch "^/assets/.*$">
    Header unset ETag
    FileETag None
    ExpiresActive On
    ExpiresDefault "access plus 1 year"
</LocationMatch>

以下是我RAILS_ROOT/config/environments/production.rb的设置:

config.cache_classes = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = false
config.assets.compress = true
config.assets.compile = false
config.assets.digest = true
config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache

你如何创建你的链接? - apneadiving
在我的布局中,我使用 <%= stylesheet_link_tag "application", :media => "all" %><%= javascript_include_tag "application" %> - DelPiero
你预编译了你的资源吗? - ka8725
是的,我有最新的Capistrano,并在我的Capfile中使用“load 'deploy/assets'”来执行此操作。但即使我手动预编译资产,仍然无法正常工作。 - DelPiero
也遇到了这个问题.. 很想知道原因。 - simonmorley
5个回答

4

3
通常情况下,您的资源应该只存在于部署应用程序的/public/assets目录中。
Apache 应该配置其DocumentRootRAILS_ROOT/public。然后,它将从RAILS_ROOT/public/assets/whatever.css提供http://example.com/assets/whatever.css,并且静态资源不会通过 Rails 处理。
自从您预编译资源以来,您是否重新启动了应用程序?有时候 Rails 期望使用比当前部署的版本更旧或更新的已编译资源版本。

是的,重新启动了Apache、Thin,并重启了服务器...但结果仍然一样。 - DelPiero
你能否通过 http://example.com/assets/filename.ext 从浏览器访问位于 RAILS_ROOT/public/assets 中的其他文件?失败的是否只是Rails编译后的资源?同时,你能否发布你的 config/environments/production.rb 文件?我不确定为什么这些请求会在Rails中被拦截。 - Brandan
不行,无法访问位于RAILS_ROOT/public/assets的任何文件。它们都是404错误。我将在我的production.rb中更新帖子。 - DelPiero
1
我正在寻找的那一行是 config.serve_static_assets = false,你已经有了。这听起来像是 Apache 的问题。RAILS_ROOT/public/assets 的所有权和权限是什么? - Brandan
权限看起来没问题,lrwxrwxrwx myuser myuser,其中myuser是我在deploy.rb中使用的相同用户。 public/assets 内的所有资产都具有相同的权限。 - DelPiero

2
我已经遇到了这个问题好几天了。一开始以为是capistrano或ruby版本的问题,但现在我相当确定也与权限有关。
我的配置基本上和你的一样,不过我还使用了Unicorn。
以下是我采取的措施:
  1. Temporarily remove the following section because I think that was causing problems with the troubleshooting:

     <LocationMatch "^/assets/.*$">
      Header unset ETag
        FileETag None
        ExpiresActive On
        ExpiresDefault "access plus 1 year"
      </LocationMatch>
    

也许先让它全部工作起来,然后再添加回去。我不认为它是问题的原因,然而在诊断这样的问题时,最好尽可能地删除一切以找到罪魁祸首。

  1. 在 public 目录上运行 chown -R xxx.xxx(将 xxx 替换为您的应用程序用户或 Web 用户)。我这样做后,CSS 再次出现。

  2. (我所做的,但可能不是必要的)您可能还想在没有 cap 的情况下本地安装,以防出现问题。对我也起作用了。

  3. 完全清除 tmp/cache 和 public/*,以防万一。

  4. 多次重启您的 Apache 服务器。

您可以在 此处 查看我的配置要点。


你能澄清一下你所说的“暂时删除该部分”是指哪个部分吗?我已经对这个问题束手无策了,现在我会尝试任何方法! - DelPiero
抱歉,由于某些原因我的回答有点遗漏。我会在几分钟内更新我的回答。我知道你的痛苦... - simonmorley
@DelPiero 如果你的问题已经解决,你应该真正接受一个答案。 - simonmorley

1

0
乘客知道这是一个RoR应用程序,因为有一个config.ru文件。
我遇到了你报告的相同错误,原因是权限不正确。Apache无法提供assets内部的文件,但可以发送public/中的文件。
在我的情况下,我使用capistrano,因此assets是一个符号链接到shared/public/assets
我所做的是:
chmod -R o+x shared/ 

需要 x 权限才能列出和访问目录。之后它就可以工作了。你必须确保 assets 对其他人有 +x 权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接