Rails 4:未在生产中加载的资产

时间:2013-09-09 14:09:54

标签: ruby-on-rails ruby asset-pipeline ruby-on-rails-4

我正在尝试将我的应用投入生产,图片和css资源路径无效。

以下是我目前正在做的事情:

  • 图片资源位于/app/assets/images/image.jpg
  • 样式表位于/app/assets/stylesheets/style.css
  • 在我的布局中,我像这样引用css文件:<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
  • 在重新启动独角兽之前,我运行RAILS_ENV=production bundle exec rake assets:precompile并且它成功了,我在public/assets目录中看到了指纹文件。

当我浏览到我的网站时,我发现mysite.com/stylesheets/styles.css找不到404错误。

我做错了什么?

更新 在我的布局中,它看起来像这样:

<%= stylesheet_link_tag    "bootstrap.min", media: "all", "data-turbolinks-track" => true %>
<%= stylesheet_link_tag    "styles", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>

生成源是:

<link data-turbolinks-track="true" href="/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/stylesheets/styles.css" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/application-0c647c942c6eff10ad92f1f2b0c64efe.js"></script>

看起来Rails没有正确查找已编译的css文件。但是它非常令人困惑为什么它正在为javascripts正常工作(注意/assets/****.js路径)。

18 个答案:

答案 0 :(得分:101)

在rails 4中,您需要进行以下更改:

config.assets.compile = true
config.assets.precompile =  ['*.js', '*.css', '*.css.erb'] 

这适用于我。使用以下命令预编译资产

RAILS_ENV=production bundle exec rake assets:precompile

祝你好运!

答案 1 :(得分:82)

我遇到了同样的问题,在config / environments / production.rb中找到了这个设置:

# Rails 4:
config.serve_static_assets = false

# Or for Rails 5:
config.public_file_server.enabled = false

将其更改为true使其正常运行。看来默认情况下,Rails希望您已经配置了前端Web服务器来处理公共文件夹外的文件请求,而不是将它们代理到Rails应用程序。也许你已经为你的javascript文件而不是你的CSS样式表做了这个?

See Rails 5 documentation)。如评论中所述,使用Rails 5,您可以设置RAILS_SERVE_STATIC_FILES环境变量,因为默认设置为config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

答案 2 :(得分:32)

/config/environments/production.rb我必须添加:

Rails.application.config.assets.precompile += %w( *.js ^[^_]*.css *.css.erb )

.js已经预编译了,但无论如何我添加了它。 .css和.css.erb显然不会自动发生。 ^[^_]排除了部分编译 - 它是一个正则表达式。

有些令人沮丧的是,文档明确指出默认情况下启用了资产管道,但没有说明只适用于javascripts的事实。

答案 3 :(得分:22)

我能够通过改变来解决这个问题: config.assets.compile = false
config.assets.compile = true

中的/config/environments/production.rb

更新(2018年6月24日):如果您使用的Sprockets版本低于2.12.5,3.7.2或4.0.0,则此方法会创建a security vulnerability .beta8

答案 4 :(得分:11)

对于Rails 5,您应该启用以下配置代码:

config.public_file_server.enabled = true

默认情况下,Rails 5附带此行配置:

config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

因此,您需要将环境变量RAILS_SERVE_STATIC_FILES设置为true。

答案 5 :(得分:10)

在生产中为资产提供服务必须完成两件事:

  1. 预编译资产。
  2. 将服务器上的资产投放到浏览器。
  3. 1)为了预编译资产,您有多种选择。

    • 您可以在本地计算机上运行rake assets:precompile,将其提交到源代码控制(git),然后运行部署程序,例如capistrano。这不是将预编译资产提交给SCM的好方法。

    • 在重新启动服务器之前,每次将Rails应用程序部署到生产环境时,都可以编写一个在目标服务器上运行RAILS_ENV=production rake assets:precompile的rake任务。

    capistrano任务中的代码看起来与此类似:

    on roles(:app) do
      if DEPLOY_ENV == 'production'
        execute("cd #{DEPLOY_TO_DIR}/current && RAILS_ENV=production rvm #{ruby_string} do rake assets:precompile")
      end
    end
    

    2)现在,您拥有生产服务器上的资产,您需要将它们提供给浏览器。

    同样,你有几个选择。

    • config / environments / production.rb

      中启用Rails静态文件服务
      config.serve_static_assets = true # old
      
      or
      
      config.serve_static_files = true # new
      

      使用Rails提供静态文件会破坏您的Rails应用程序性能。

    • 配置nginx(或Apache)以提供静态文件。

      例如,配置为与Puma一起使用的我的nginx如下所示:

      location ~ ^/(assets|images|fonts)/(.*)$ {
          alias /var/www/foster_care/current/public/$1/$2;
          gzip on;
          expires max;
          add_header Cache-Control public;
      }
      

答案 6 :(得分:4)

Rails 4不再生成资产的非指纹版本:不会为您生成stylesheets / style.css。

如果您使用stylesheet_link_tag,则会生成到样式表的正确链接

此外styles.css应该在config.assets.precompile中,这是预编译的内容列表

答案 7 :(得分:3)

你不应该做的事情:

上面的一些同事建议你这样做:

config.serve_static_assets = true  ## DON”T DO THIS!! 
config.public_file_server.enabled = true ## DON”T DO THIS!!

rails资产管道说明了上述方法:

  

此模式使用更多内存,执行效果比默认值差,不推荐使用。见这里:(http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation

你应该做什么:

<强> 1。预编译您的资产。

RAILS_ENV=production rake assets:precompile

<强> 2。将这些文件添加到git。

git add –-all

第3。将更改推送到主分支并重新部署。

git push origin master

答案 8 :(得分:3)

更改您的Production.rb文件行

config.assets.compile = false

进入

config.assets.compile = true

并添加

config.assets.precompile =  ['*.js', '*.css', '*.css.erb']

答案 9 :(得分:2)

如果设置了预编译,则不需要

config.assets.compile = true

因为这是为了提供资产。

我们的问题是我们只在config/secrets.yml

中设置了开发密钥基础
development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

需要进入生产环境

答案 10 :(得分:2)

我正在运行 Ubuntu Server 14.04 Ruby 2.2.1 Rails 4.2.4 我已经按照部署{{3}进行了操作一切顺利,但当我进入浏览器并输入我的VPS的IP地址时,我的应用程序已加载,但没有样式和JavaScript。

该应用正在使用 Unicorn Nginx 运行。要解决此问题,我使用SSH与我的用户 '部署者' 进入我的服务器,然后转到我的应用路径 '/ home / deployer / apps / blog' 并运行以下命令:

RAILS_ENV=production bin/rake assets:precompile

然后我只是重新启动VPS就是这样! 它对我有用!

希望它对其他人有用!

答案 11 :(得分:1)

首先检查您的资产,预编译资产时可能会出现一些错误。

要在生产环境中预编译资产,请运行以下命令:

RAILS_ENV=production rake assets:precompile

如果显示错误,请先删除

如果出现“未定义变量”错误,请在将该变量文件用于另一个文件之前加载该文件。

示例:

@import "variables";
@import "style";

在application.rb文件中设置资产预编译序列

示例:

config.assets.precompile += [ 'application.js', 'admin.js', 'admin/events.js', 'admin/gallery.js', 'frontendgallery.js']

config.assets.precompile += [ 'application.css', 'admin.css','admin/events.css', 'admin/gallery.css', 'frontendgallery.css']

答案 12 :(得分:1)

发现这个:

配置选项config.serve_static_assets已重命名为config.serve_static_files以澄清其角色。

config/environments/production.rb中的

# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?

因此设置env RAILS_SERVE_STATIC_FILES或使用Nginx来提供静态文件。 添加config.serve_static_assets = true仍然可以使用,但将来会删除。

答案 13 :(得分:1)

不建议让capistrano执行资产预编译,因为它可能需要很长时间并且经常超时。尝试做本地资产预编译。

1,在config / application.rb中设置 config.assets.initialize_on_precompile = false 然后做当地的 RAILS_ENV=production bin/rake assets:precompile 并将这些公共/资产添加到git。

和config / environments / development.rb,更改资产路径以避免使用预编译资产:

config.assets.prefix = '/dev-assets'

如果您有数据库连接问题,则意味着您拥有使用db的初始化程序。另一种方法是通过重复生产设置新环境.rb可能 production2 .rb,并在database.yml中,使用开发<添加 production2 环境/ strong>数据库设置。然后做

RAILS_ENV=production2 bin/rake assets:precompile

如果您仍然面临资产问题,例如ckeditor, 将js文件添加到config / initializers / assets.rb

Rails.application.config.assets.precompile += %w( ckeditor.js )

答案 14 :(得分:1)

  

用于编译文件的默认匹配器包括application.js,application.css和所有非JS / CSS文件(这将自动包括所有图像资源)来自app / assets文件夹,包括你的宝石:

     

如果要包含其他清单或单个样式表和JavaScript文件,可以将它们添加到config / initializers / assets.rb中的预编译数组中:

Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']

http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets

答案 15 :(得分:0)

我可能错了,但建议改变的人

config.assets.compile = true

此行的评论如下:#如果遗漏了预编译资产,#不会回退到资产管道。

这表明通过将此设置为true,您无法解决问题,而是绕过它并每次都运行管道。这肯定会扼杀你的表现并挫败管道的目的吗?

我遇到了同样的错误,这是因为应用程序在rails不知道的子文件夹中运行。

所以我的css文件在home / subfolder / app / public / ....但是rails在home / app / public /...

尝试将您的应用移出子文件夹或告诉rails它是否在子文件夹中。

答案 16 :(得分:0)

location ~ ^/assets/ {
  expires 1y;
  add_header Cache-Control public;
  add_header ETag "";
}

这解决了我在生产中遇到的问题。把它放入nginx配置。

答案 17 :(得分:0)

即使我们遇到RAILS_ENV=production bundle exec rake assets:precompile成功但事情没有按预期发挥作用的同样问题 我们发现独角兽是这里的罪魁祸首。

与您的情况相同,即使我们曾经在编译资产后重启unicorn。注意到,当重新启动独角兽时,只重新启动其工作进程而不是主进程 这是未提供正确资产的主要原因。

稍后,在编译资产后,我们停止并启动了独角兽,以便重新启动独角兽主进程并获得正确的资产。
与重新启动独角兽相比,停止和启动独角兽会导致大约10秒的停机时间。这是一种解决方法,可用于长期解决方案从独角兽迁移到美洲狮的地方。