rails - 在生产模式下找不到application.css资产

Mic*_*ant 29 css ruby-on-rails ruby-on-rails-3 asset-pipeline

我正在升级应用程序以使用资产管道.

我已经将css资产编译成应用程序css文件但是当我在生产模式下运行应用程序时找不到它们

RAILS_ENV=production bundle exec rails s
Run Code Online (Sandbox Code Playgroud)

我访问任何页面,我从数据库中获得正确的输出,但没有样式和日志显示:

ActionController::RoutingError (No route matches [GET] 
"/assets/default.scss-1a27c...f07c.css"):
Run Code Online (Sandbox Code Playgroud)

即使该文件存在于公共/资产中

$ ls public/assets/def*
public/assets/default.scss-1a27c...f07c.css     public/assets/default.scss.css
public/assets/default.scss-1a27c...f07c.css.gz  public/assets/default.scss.css.gz
Run Code Online (Sandbox Code Playgroud)

我需要更改什么才能让服务器找到资产文件?

我的其他.css文件也是如此.他们用指纹编译成公共/资产,但后来找不到.

页面来源显示:

<link href="/assets/default.scss-1a27c...f07c.css" 
media="screen" rel="stylesheet" type="text/css" />
Run Code Online (Sandbox Code Playgroud)

rails(haml)源是 = stylesheet_link_tag 'default.scss.css'

public.assets curently包括以下文件.

$ ls public/assets/def*
public/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css
public/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css.gz
public/assets/default.scss.css
public/assets/default.scss.css.gz
Run Code Online (Sandbox Code Playgroud)

application.rb有

$ cat config/application.rb 
require File.expand_path('../boot', __FILE__)

# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line
  # Bundler.require(:default, :assets, Rails.env)
end

module Linker
  class Application < Rails::Application
    config.encoding = "utf-8"
    config.filter_parameters += [:password]
    config.assets.enabled = true
    config.assets.initialize_on_precompile = false # For Heroku
    config.assets.version = '1.0'
  end
end
Run Code Online (Sandbox Code Playgroud)

config/environments/production 具有:

$ cat config/environments/production.rb 
Linker::Application.configure do
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true
  config.assets.precompile += ['default.scss.css','main.css', 'jquery-ui-1.8.22.custom.css']
  config.serve_static_assets = false
  config.assets.compress = true
  config.assets.compile = false
  config.assets.digest = true
  config.log_level = :debug
  config.i18n.fallbacks = true
  config.active_support.deprecation = :notify
end
Run Code Online (Sandbox Code Playgroud)

这似乎发生在所有资产上,例如

Started GET "/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css"):
Started GET "/assets/main-6864687b4114a1c316e444bd90f233ff.css" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/main-6864687b4114a1c316e444bd90f233ff.css"):
Started GET "/assets/jquery-ui-1.8.22.custom-24319b4b1218846a3fe22a0479ae98b4.css" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/jquery-ui-1.8.22.custom-24319b4b1218846a3fe22a0479ae98b4.css"):
Started GET "/assets/application-fc1d492d730f2a45581a40eac4607db8.js" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/application-fc1d492d730f2a45581a40eac4607db8.js"):
Started GET "/images/link.ico" for 127.0.0.1 at 2014-02-23 10:24:48 -0500
ActionController::RoutingError (No route matches [GET] "/images/link.ico"):
Run Code Online (Sandbox Code Playgroud)

awe*_*ndt 32

默认情况下,Rails不提供资产public.看到你的production.rb:

  config.serve_static_assets = true
Run Code Online (Sandbox Code Playgroud)

改变为真,你很高兴.(注意:您不希望它true在生产中,请记住在部署之前将其更改回来!)

有关详细信息,请参阅配置Rails应用

  • 对于Rails 5:在`config/environments/production.rb`中将`config.public_file_server.enabled`设置为`true`. (7认同)
  • 我想补充一点,在Rails 5中,配置标志由`ENV ['RAILS_SERVE_STATIC_FILES']设置.存在?`这意味着您可以使用`RAILS_SERVE_STATIC_FILES = 1 rails server - environment production`运行您的服务器,您将会很好去而不改变配置文件. (3认同)
  • 为什么在生产中应该是假的?我正在使用rails_12factor和heroku。感谢您的进一步解释! (2认同)
  • @LeoBrown Rails假定在生产中,您有一个运行在Rails之前的Web服务器(Apache,nginx),或者甚至是专门用于静态资产的CDN。这些中的任何一个都可以比Rails更快地提供静态资产。 (2认同)
  • @vmarquet,我花了太多时间寻找这个答案...在生产模式中设计`<%= link_to('Logout',destroy_user_session_path,method :: delete)%>`把我带到这里,为那些不可避免地会跟随的人.谢谢! (2认同)

Ben*_*mos 10

Rails 5解决方案类似于Jules Copeland上面给出的Rails 4解决方案.

在预生成的config/environments/production.rb文件中,应该有一个看起来像这样的条目:

# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
Run Code Online (Sandbox Code Playgroud)

我在http://guides.rubyonrails.org配置Rails应用程序指南中找到了对此设置的一个不错的解释:

config.public_file_server.enabled将Rails配置为从公共目录提供静态文件.此选项默认为true,但在生产环境中,它设置为false,因为用于运行应用程序的服务器软件(例如NGINX或Apache)应该提供静态文件.如果您使用WEBrick在生产模式下运行或测试应用程序(建议不要在生产中使用WEBrick),请将该选项设置为true.否则,您将无法使用页面缓存并请求公共目录下存在的文件.

结论:在生产中,启动rails服务器RAILS_SERVE_STATIC_FILES=1将允许Rails像web服务器一样提供public/assets目录中的任何文件.请记住,Rails是一个应用服务器,不会像Web服务器那样高效(例如NGINX,Apache等).对于实际应用程序,您应该在Rails前面有一个专用的Web服务器,它将自行提供静态资产,并且只根据需要为Rails提供动态内容.有关更多详细信息,请参阅Justin Weiss关于Web服务器和应用服务器之间差异的文章.


Jul*_*and 9

在Rails 4中,您可以通过传递环境变量让它们在生产中显示(在本地运行):

RAILS_SERVE_STATIC_FILES=true rails server -e production

只要你有这一行,这应该有效/config/environments/production.rb:

config.serve_static_files = ENV ['RAILS_SERVE_STATIC_FILES'].现在?