首页 文章

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

提问于
浏览
105

我正在尝试将我的应用程序投入 生产环境 ,图像和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未找到错误 .

我究竟做错了什么?

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

<%= 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 回答

  • 4

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

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

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

    RAILS_ENV=production bundle exec rake assets:precompile
    

    祝你好运!

  • 22

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

  • 1

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

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

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

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

  • 0

    我能够通过更改: config.assets.compile = false 来解决此问题
    config.assets.compile = true in /config/environments/production.rb

    Update (June 24, 2018) :如果您使用的Sprockets版本小于2.12.5,3.7.2或4.0.0.beta8,则此方法会创建a security vulnerability

  • 0

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

  • 0

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

    • 预编译资产 .

    • 将服务器上的资产提供给浏览器 .

    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

    要么

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

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

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

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

  • 9

    更改您的Production.rb文件行

    config.assets.compile = false
    

    config.assets.compile = true
    

    并且还添加

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

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

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

    RAILS_ENV=production bin/rake assets:precompile
    

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

    希望它对其他人有用!

  • 10

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

    config.assets.compile = true
    

    因为这是为了服务资产 .

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

    development:
        secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'
    

    需要进入 生产环境 环境

  • 75

    你不应该做的事:

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

    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. Precompile your assets.

    RAILS_ENV=production rake assets:precompile

    2. Add those files to git.

    git add –all

    3. Push to heroku.

    git push origin master

  • 2

    用于编译文件的默认匹配器包括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

  • 2

    发现这个:

    配置选项 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 仍然有效,但将来会删除 .

  • 3

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

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

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

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

    config.assets.compile = true

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

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

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

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

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

  • 0

    不建议让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中,添加具有 development db设置的 production2 环境 . 然后做

    RAILS_ENV=production2 bin/rake assets:precompile

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

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

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

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

  • 31

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

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

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

相关问题