121

我正在尝试将我的应用程序投入生产,但图像和 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 文件。但是为什么它对 javascripts 正常工作非常令人困惑(注意/assets/****.js路径)。

4

18 回答 18

107

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

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

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

RAILS_ENV=production bundle exec rake assets:precompile

祝你好运!

于 2014-02-10T07:32:55.967 回答
87

我刚刚遇到了同样的问题,并在 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?.

于 2014-12-05T14:59:11.950 回答
33

/config/environments/production.rb我不得不添加这个:

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

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

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

于 2013-09-09T15:40:29.770 回答
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,此方法会产生安全漏洞

于 2014-01-30T06:49:34.177 回答
17

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

于 2016-10-12T05:14:29.323 回答
10

要为生产中的资产提供服务,您必须完成 2 件事:

  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;
    }
    
于 2016-06-05T03:03:10.447 回答
4

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

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

另外styles.css应该在config.assets.precompilewhich 是预编译的东西的列表

于 2013-09-09T14:18:03.927 回答
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

你应该做什么:

预编译您的资产。

RAILS_ENV=production rake assets:precompile

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

于 2018-04-11T03:08:48.207 回答
3

更改您的 Production.rb 文件行

config.assets.compile = false

进入

config.assets.compile = true

并添加

config.assets.precompile =  ['*.js', '*.css', '*.css.erb']
于 2015-09-25T11:33:06.013 回答
2

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

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

RAILS_ENV=production bin/rake assets:precompile

然后我只需重新启动 VPS 就可以了!这个对我有用!

希望它对其他人有用!

于 2015-09-09T05:51:58.763 回答
2

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

config.assets.compile = true

因为这是为资产实时服务。

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

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

需要进入生产环境

于 2015-10-16T12:38:16.703 回答
1

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

如果您有其他清单或单独的样式表和 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

于 2015-01-15T05:17:05.013 回答
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']
于 2016-01-20T06:51:21.327 回答
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?

所以设置 envRAILS_SERVE_STATIC_FILES或 usingNginx来提供静态文件。添加config.serve_static_assets = true仍然有效,但将来会被删除。

于 2016-02-29T04:14:24.963 回答
1

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

1st,在 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 连接问题,则意味着您有使用 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 )

于 2017-03-09T16:22:18.457 回答
0

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

config.assets.compile = true

此行的注释为:#Do not fallback to assets pipeline if a precompiled assets丢失。

这表明通过将其设置为 true 您并没有解决问题,而是绕过它并每次运行管道。这肯定会扼杀你的表现并破坏管道的目的吗?

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

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

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

于 2016-10-25T11:46:03.670 回答
0

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

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

后来,在编译完资产后,我们停止并启动了 unicorn,这样 unicorn 主进程也重新启动,并提供了正确的资产。
与重启独角兽相比,停止和启动独角兽会带来大约 10 秒的停机时间。这是可以在长期解决方案从独角兽转向 puma 的情况下使用的解决方法。

于 2017-06-14T13:53:44.700 回答
0
location ~ ^/assets/ {
  expires 1y;
  add_header Cache-Control public;
  add_header ETag "";
}

这解决了我在生产中的问题。将其放入 nginx 配置中。

于 2017-03-29T09:18:56.583 回答