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

问题描述 投票:112回答:18

我正在尝试将我的应用程序投入生产,图像和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 not found错误。

我究竟做错了什么?

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

<%= 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路径)是非常令人困惑的。

ruby-on-rails ruby asset-pipeline ruby-on-rails-4
18个回答
102
投票

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

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

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

RAILS_ENV=production bundle exec rake assets:precompile

祝你好运!


2
投票

我正在运行Ubuntu Server 14.04,Ruby 2.2.1和Rails 4.2.4我已经关注部署turorial from DigitalOcean并且一切顺利但当我进入浏览器并输入我的VPS的IP地址时我的应用程序已加载但没有样式和JavaScript的。

该应用程序与Unicorn和Nginx一起运行。为了解决这个问题,我使用SSH和我的用户'deployer'进入我的服务器,然后转到我的应用程序路径'/ home / deployer / apps / blog'并运行以下命令:

RAILS_ENV=production bin/rake assets:precompile

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

希望它对其他人有用!


2
投票

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

config.assets.compile = true

因为这是为了服务资产。

我们的问题是我们在config/secrets.yml中只设置了开发秘密密钥库

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

需要进入生产环境


1
投票

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

如果要包含其他清单或单个样式表和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


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']

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仍然有效,但将来会删除。


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的初始化程序。一种方法是通过复制production.rb设置一个新环境,可能是production2.rb,在database.yml中,添加具有开发数据库设置的production2环境。然后做

RAILS_ENV=production2 bin/rake assets:precompile

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

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


0
投票

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

config.assets.compile = true

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

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

我有同样的错误,这是由于应用程序在rails不知道的子文件夹中运行。

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

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


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

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


0
投票

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

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

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


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?


32
投票

/config/environments/production.rb,我不得不补充一点:

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

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

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


23
投票

我能够通过改变: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.beta8,则此方法创建a security vulnerability


13
投票

对于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。


10
投票

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

  1. 预编译资产。
  2. 将服务器上的资产提供给浏览器。

1)为了预编译资产,您有多种选择。

  • 您可以在本地计算机上运行rake assets:precompile,将其提交到源代码控制(git),然后运行部署程序,例如capistrano。这不是将预编译资产提交给SCM的好方法。
  • 在重新启动服务器之前,每次将Rails应用程序部署到生产环境时,您都可以编写一个rake任务,在目标服务器上运行RAILS_ENV=production rake assets:precompile

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; }

4
投票

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

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

另外styles.css应该在config.assets.precompile中,这是预编译的东西列表


3
投票

更改您的Production.rb文件行

config.assets.compile = false

config.assets.compile = true

并且还添加

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

3
投票

What you SHOULD NOT do:

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

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

What you SHOULD do:

预编译您的资产。

RAILS_ENV=production rake assets:precompile

你可以用rake任务做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.