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


116

我正在尝试将我的应用程序投入生产,并且图像和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目录中看到了指纹文件。

浏览到我的网站时,出现的404 not found错误mysite.com/stylesheets/styles.css

我究竟做错了什么?

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

<%= 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文件。但这很令人困惑,为什么它对于javascript仍然可以正常工作(注意/assets/****.js路径)。


您能告诉我们如何加载CSS文件吗?从您的错误看来,您尝试硬链接而不是使用stylesheet_link_tag
kik 2013年

1
刚刚在上面添加。我正在做<%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" => true %>
emersonthis

好的,所以我要提出两点建议:1.检查生成的源代码(如果此行被写为的路径)public/assets; 2.仔细检查是否有其他指令试图加载该css文件(可能是硬编码的)
kik

我不能说使用.erb是否有问题,因为我从来没有这样做:.home {background: #FFF url(<%= image_path 'hippopotamus.jpg' %>) no-repeat; }实际上可以用替换在链轮中.home {background: #FFF url(image-path('hippopotamus.jpg')) no-repeat; }。也许您可以尝试一下,如果有帮助。
kik 2013年

您是说我可以在css文件中使该引用动态化,而无需添加.erb扩展名吗?我进行了更改,因为在开发模式下,我不希望链接断开。
emersonthis

Answers:


105

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

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

这对我有用。使用以下命令预编译资产

RAILS_ENV=production bundle exec rake assets:precompile

祝你好运!


11
我认为将config.assets.compile设置为true会破坏生产性能。还有,css.erb?谁用的?那子和咖啡呢?
ahnbizcad 2014年

当请求coffee和sass文件时,它们由coffee-script和sass-rails gem提供的处理器处理,然后分别作为JavaScript和CSS发送回浏览器。
Rameshwar Vyevhare 2014年

1
这个问题已经为Rails 4解决,因此无需使用turbo-sprocket-
rails3

4
抱歉,我无法将您所说的与我的问题联系起来。
ahnbizcad 2014年

1
通常,当您运行生产服务器时,您将在Apache或nginx Web服务器后面运行乘客或独角兽或彪马的Rails。最好让Apache或nginx提供静态文件(js,css,图像),让Rails应用程序服务器(puma,unicorn)提供Rails代码和模板。为此,您应该关闭config.serve_static_files,并在Apache和nginx中配置别名以处理assets
洲鸿岭市

85

我只是遇到了同样的问题,并在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样式表完成此操作的?

请参阅Rails 5文档)。如注释中所述,在Rails 5中,您可以只设置RAILS_SERVE_STATIC_FILES环境变量,因为默认设置为config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?


1
弃用警告:配置选项config.serve_static_assets已重命名为,config.serve_static_files以阐明其作用(它仅能提供public文件夹中的所有内容,并且与资产管道无关)。该serve_static_assets别名将在Rails的5.0被删除。请相应地迁移您的配置文件。
yekta 2015年

早些时候,当我面对这个问题时,改变那条线已经为我解决了,但是现在我又面对了它(我不知道在这种情况下我会如何继续前进),这还不够。关于什么可能有什么更多的建议?
IIllIIll 2015年

2
这应该是公认的答案。尽管它config.serve_static_files在Rails 4.2config.public_file_server.enabledRails 5中。@see github.com/heroku/rails_serve_static_assets/blob/master/lib/...
卢卡斯尼尔森

3
Rails 5.0.0.1 config / environments / production.rb包含了它,config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?因此您可以为您的环境进行不同的设置,而无需更改签入SCM的代码。
tobinjim

启用它:“ export RAILS_SERVE_STATIC_FILES =”然后运行“ rails s -e production”禁用它:“ unset RAILS_SERVE_STATIC_FILES”
Alfredo Osorio

32

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

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

.js已经进行了预编译,但是我还是添加了它。.css和.css.erb显然不会自动发生。在^[^_]不包括来自谐音被编译-这是一个正则表达式。

令人沮丧的是,该文档明确指出默认情况下资产管道已启用,但并未阐明仅适用于javascript的事实。


您需要将styles.css添加到config.assets.precompile
Frederick Cheung

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,则此方法会创建一个安全漏洞


7
这不是说Rails正在编译资产,而不是从CDN加载资产吗?
本杰明·奥克斯

@BenjaminOakes是的,那就是我想要的
Yanofsky

2
与默认模式相比,此模式使用更多的内存,性能较差,因此不建议这样做。最好使用Nginx代理。
yekta 2015年

16

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


1
对于Rails 5,我应该添加passenger_env_var RAILS_SERVE_STATIC_FILES true;我在nginx.conf文件中的应用程序的位置块中设置的内容。
Martin Velez

10

服务生产中的资产必须完成两件事:

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

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

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

  • 您可以编写RAILS_ENV=production rake assets:precompile每次在将Rails应用程序部署到生产环境时都在目标服务器上运行的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;
    }

4

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

如果使用,stylesheet_link_tag则将生成指向样式表的正确链接

另外styles.css应该在config.assets.precompile其中列出预编译的事物


我在/ public / assets /目录中看到了指纹文件。在我的布局中,我有这个:<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>这不正确吗?
emersonthis

由于某些原因,当我查看源代码时,生产部署仍指向原始文件,<link data-turbolinks-track="true" href="https://stackoverflow.com/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />但是javascript文件是正确的!我不明白为什么相同的配置适用于.js文件而不适用于.css。
emersonthis 2013年

在Rails 5.0.0.beta3上,我收到以下警告:DEPRECATION WARNING:serve_static_files已弃用,并将在Rails 5.1中删除。请public_file_server.enabled = true改用。
GMA

@emersonthis一样!Js完美加载,但某些CSS文件得到了404。您解决了吗?
IvRRimUm

资产管道配置几乎总是有问题。如果您将文件放在非默认位置,则几乎可以肯定是问题所在,您需要使用第一个答案之类的内容来告知资产管道。
emersonthis

3

更改您的Production.rb文件行

config.assets.compile = false

进入

config.assets.compile = true

并添加

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

为什么要编译?我们不打算在生产过程中进行生产编译
James Tan

1
绝对不要这样做!在生产环境中将config.assets.compile设置为true的任何人都应该被射击。
bkunzi01 '01 -10-12

2

我正在运行Ubuntu Server 14.04Ruby 2.2.1Rails 4.2.4,我遵循了DigitalOcean的部署指南,一切进展顺利,但是当我进入浏览器并输入VPS的IP地址时,我的应用已加载,但没有样式和javascript。

该应用程序与UnicornNginx一起运行。为了解决这个问题,我使用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
如您需要config.assets.precompile = ['*.js', '*.css', '*.css.erb'] 并运行的其他答案中所述RAILS_ENV=production bundle exec rake assets:precompile
xxjjnn 2015年

1
这使得在生产过程中进行资产编译非常慢,不正确
James Tan

2

您不应该做的事情:

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

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

您应该做什么:

预编译您的资产。

RAILS_ENV=production rake assets:precompile

您可以通过执行rake任务来做到这一点。


为什么要在git中添加构件?您可以将rake任务添加到您的构建过程中,避免大量gitspam(尤其是如果您使用uglifier和gzipping,则应该这样做)
Dr.Strangelove

@ Dr.Strangelove谢谢您的评论-我对此不太了解-:您能详细说明/编辑原始帖子吗?
BKSpurgeon '19

1

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

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

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

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

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_FILESNginx用于提供静态文件。添加config.serve_static_assets = true仍然可以使用,但是将来会删除。


1

不建议让capistrano对资产进行预编译,因为这可能会花费很多时间,并且经常会超时。尝试对本地资产进行预编译。

首先,在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'

如果您有数据库连接问题,则意味着您拥有使用数据库的初始化程序。解决该问题的一种方法是通过复制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成功的同一问题,但事情并没有按预期进行。
我们发现独角兽是这里的罪魁祸首。

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

后来,在整理资产后,我们停止并启动了独角兽,以便重新启动独角兽主流程并提供正确的资产。
与重新启动独角兽相比,停止和启动独角兽会导致大约10秒钟的停机时间。当长期解决方案从独角兽转移到美洲狮时,可以使用此解决方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.