Ruby-on-rails Rails 应用程序不在生产环境中为资产提供服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17904949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails App Not Serving Assets in Production Environment
提问by septerr
My app works fine when run in development environment. In production (rails server -e production), the browser can't access the css and js files and on the console there are messages like:
我的应用程序在开发环境中运行时运行良好。在生产 ( rails server -e production) 中,浏览器无法访问 css 和 js 文件,并且在控制台上有如下消息:
I, [2013-07-27T21:00:59.105459 #11449] INFO -- : Started GET "/javascripts/application.js" for 99.102.22.124 at 2013-07-27 21:00:59 +0000
F, [2013-07-27T21:00:59.108302 #11449] FATAL -- :
ActionController::RoutingError (No route matches [GET] "/javascripts/application.js"):
The head section from html source when in production environment:
在生产环境中来自 html 源代码的 head 部分:
<head>
<title>a Social Server</title>
<link data-turbolinks-track="true" href="/stylesheets/application.css" media="all" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<script data-turbolinks-track="true" src="/javascripts/application.js"></script>
<meta content="authenticity_token" name="csrf-param">
<meta content="jYM4IAXTXAuKWeD4FEVrXgXRNFeB6EazU68ZBQfRqNY=" name="csrf-token">
</head>
In development env on the other hand the head section looks like:
另一方面,在开发环境中,头部部分看起来像:
<head>
<title>a Social Server</title>
<link data-turbolinks-track="true" href="/assets/application.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/twitter-bootstrap-static/bootstrap.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/twitter-bootstrap-static/fontawesome.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/bootstrap_and_overrides.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/instagram.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/socialserver.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.core.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.theme.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.accordion.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.menu.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.autocomplete.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.button.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.datepicker.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.resizable.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.dialog.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.progressbar.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.selectable.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.slider.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.spinner.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.tabs.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.tooltip.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.base.css?body=1" media="all" rel="stylesheet">
<link data-turbolinks-track="true" href="/assets/jquery.ui.all.css?body=1" media="all" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<script data-turbolinks-track="true" src="/assets/jquery.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery_ujs.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-transition.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-alert.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-modal.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-dropdown.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-scrollspy.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-tab.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-tooltip.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-popover.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-button.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-collapse.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-carousel.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-typeahead.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap/bootstrap-affix.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/bootstrap.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/turbolinks.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/bootstrap.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.core.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.widget.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.accordion.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.position.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.menu.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.autocomplete.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.button.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.datepicker.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.mouse.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.draggable.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.resizable.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.dialog.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.droppable.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-blind.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-bounce.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-clip.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-drop.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-explode.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-fade.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-fold.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-highlight.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-pulsate.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-scale.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-shake.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-slide.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.effect-transfer.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.progressbar.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.selectable.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.slider.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.sortable.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.spinner.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.tabs.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.tooltip.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery.ui.all.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/application.js?body=1"></script>
<meta content="authenticity_token" name="csrf-param">
<meta content="jYM4IAXTXAuKWeD4FEVrXgXRNFeB6EazU68ZBQfRqNY=" name="csrf-token">
</head>
The app does not use a database, so I have disabled ActiveRecord. Snippets of the config files:
该应用程序不使用数据库,因此我禁用了 ActiveRecord。配置文件的片段:
application.rb
应用程序.rb
require File.expand_path('../boot', __FILE__)
#require 'rails/all'
require "action_controller/railtie"
require "action_mailer/railtie"
require "rails/test_unit/railtie"
require "sprockets/railtie"
Bundler.require(:default, Rails.env)
module Socialserver
class Application < Rails::Application
end
end
production.rb
生产.rb
Socialserver::Application.configure do
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = false
config.assets.js_compressor = :uglifier
config.assets.compile = false
config.assets.digest = true
config.assets.version = '1.0'
config.log_level = :info
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
config.log_formatter = ::Logger::Formatter.new
config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
config.assets.precompile += %w( .svg .eot .woff .ttf )
end
development.rb:
开发.rb:
Socialserver::Application.configure do
config.cache_classes = false
config.eager_load = false
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_mailer.raise_delivery_errors = false
config.active_support.deprecation = :log
config.assets.debug = true
end
Gemfile:
宝石档案:
source 'https://rubygems.org'
gem 'rails', '4.0.0'
gem 'sass-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
group :doc do
gem 'sdoc', require: false
end
group :twitter do
gem 'twitter', '4.8.1'
end
group :instagram do
gem 'instagram', '0.10.0'
end
group :tumblr do
gem 'tumblr_client'
end
gem 'twitter-bootstrap-rails'
gem 'therubyracer' #needed for runtime js on amazon ec2.
I apologize for posting so much info. I felt the info might be relevant.
我很抱歉发布了这么多信息。我觉得这些信息可能是相关的。
p.s. I have only half baked knowledge of rails, so bear with me. Thanks~
ps我对rails只有半生不熟的知识,所以请耐心等待。谢谢~
回答by jibai31
When testing locally your production environment, you have to compile the assets locally. Simply run the command below:
在本地测试您的生产环境时,您必须在本地编译资产。只需运行以下命令:
RAILS_ENV=production bundle exec rake assets:precompile
It will generate all the assets under public/assets.
它将生成 下的所有资产public/assets。
Next, you have to tell Rails to serve the assets itself. Server software (eg. Nginx or Apache) do it for you on environments like Heroku, but locally you should let Rails do it. Change this in your production.rb:
接下来,您必须告诉 Rails 为资产本身提供服务。服务器软件(例如 Nginx 或 Apache)在 Heroku 等环境中为您完成,但在本地您应该让 Rails 完成。在您的production.rb:
config.serve_static_assets = true
But make sure you set it back to falsebefore pushing your code to production!
但是请确保false在将代码投入生产之前将其设置回!
回答by pix
This sounds like to the problem I was having.
I found a blogthat suggests this is a bug in the Rails 4.0.0 asset pipeline, and is inexplicably mitigated by setting...
我发现一个博客表明这是 Rails 4.0.0 资产管道中的一个错误,并且通过设置...
config.assets.compile = true
... in config/environments/production.rb
... 在 config/environments/production.rb
Aside from somehow kicking the asset pipeline in to actually working, that setting will turn on live-compilation of assets. That is normally a bad thing for performance in production, but if you still manually precompile assets when you deploy, with
除了以某种方式将资产管道踢入实际工作之外,该设置还将开启资产的实时编译。这对于生产中的性能来说通常是一件坏事,但是如果您在部署时仍然手动预编译资产,
rake assets:precompile
... the live-compilation should never happen (because the necessary assets have already been precompiled).
...实时编译不应该发生(因为已经预编译了必要的资产)。
I hope this helps :)
我希望这有帮助 :)
回答by James B. Byrne
As previously noted config.serve_static_assetsis deprecated and replaced by config.serve_static_files. If one examines config/environments/production.rbfor Rails-4.2 then one finds this:
如前所述,config.serve_static_assets已弃用并由config.serve_static_files. 如果检查config/environments/production.rbRails-4.2,就会发现:
# 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?
The implication being that setting and exporting (in BASH) the environment variable export RAILS_SERVE_STATIC_FILES="to any value whatsoever"in a session prior to running rails s -e productionwill give the desired result when testing locally and also will avoid having to remember to recode production.rbbefore pushing to the production host.
这意味着在export RAILS_SERVE_STATIC_FILES="to any value whatsoever"运行之前在会话中设置和导出(在 BASH 中)环境变量rails s -e production将在本地测试时提供所需的结果,并且还避免production.rb在推送到生产主机之前必须记住重新编码。
回答by Chris Aitchison
In production.rb change the setting:
在 production.rb 中更改设置:
rails 3.x
导轨 3.x
config.serve_static_assets = true
rails 4.x
导轨 4.x
config.serve_static_files = true
回答by Phil
Check for a file like this:
检查这样的文件:
public/assets/.sprockets-manifest-3f7771d777ceb581d754e4fad88aa69c.json
If you are pushing precompiled assets to a production server there is a chance that you are preventing hidden 'dot' files being pushed and this essential file won't make it into production.
如果您将预编译的资产推送到生产服务器,则可能会阻止推送隐藏的“点”文件,而此基本文件将无法投入生产。
In my environment I need to precompile assets in an integration environment and push these to production so that there is no need to compile the assets on the production machine. I was erroneously blocking all hidden files from being pushed to production machine.
在我的环境中,我需要在集成环境中预编译资产并将它们推送到生产中,这样就不需要在生产机器上编译资产。我错误地阻止了所有隐藏文件被推送到生产机器。
To see if this answer works for you, check your generated HTML source in a browser from the production server to see if the assets path has been generated. If you see your script tag like this:
要查看此答案是否适合您,请在来自生产服务器的浏览器中检查您生成的 HTML 源代码,以查看是否已生成资产路径。如果您看到这样的脚本标签:
<script data-turbolinks-track="true" src="/javascripts/application.js"></script>
check the src attribute. It should start with /assets/javascript. In this case it starts with /javascriptwhich indicates Rails does not think any of the assets have been precompiled.
检查 src 属性。它应该以/assets/javascript. 在这种情况下,它以/javascriptwhich开头表示 Rails 认为没有预编译任何资产。
I corrected this by updating my push to production (currently rsync), ensuring I push the .sprockets-manifest*file after precompiling on my integration server.
我通过更新我的推送到生产(当前是 rsync)来纠正这个问题,确保.sprockets-manifest*在我的集成服务器上预编译后推送文件。
Also, I use standalone Passenger as my integration test server, rather than Webrick, since it handles more realistic serving of static files.
此外,我使用独立的Passenger 作为我的集成测试服务器,而不是Webrick,因为它可以处理更真实的静态文件服务。
回答by Rui Andrada
I think to Rails 4.x you have to precompile assets to production or use config.assets.compile even both if needed.
我认为对于 Rails 4.x,您必须将资产预编译到生产中,或者在需要时使用 config.assets.compile 甚至两者。
The default Rails behavior for production environment is to "Do not fallback to assets pipeline if a precompiled asset is missed."So, don't. Use to not compi
生产环境的默认 Rails 行为是“如果缺少预编译资产,则不要回退到资产管道”。所以,不要。用于不编译
config.assets.compile = false
If you use this option you don't need to use:
如果您使用此选项,则不需要使用:
config.serve_static_files = true
Because if the asset wasn't precompiled, Rails will compile before serve request.
因为如果资产没有预编译,Rails 将在服务请求之前编译。
But if you do precompile the assets before production you don't needs config.assets.compile = true, but you need config.serve_static_files = trueto Rails serve requests if you don't have http_server to serve the precompiled assets.
但是,如果您在生产之前预编译资产,则不需要config.assets.compile = true,但config.serve_static_files = true如果您没有 http_server 来服务预编译资产,则需要Rails 服务请求。
The setting config.serve_static_assetsis deprecated.
该设置config.serve_static_assets已弃用。
DEPRECATION WARNING: The configuration option `config.serve_static_assets` has been renamed to `config.serve_static_files` to clarify its role (it merely enables serving everything in the `public` folder and is unrelated to the asset pipeline). The `serve_static_assets` alias will be removed in Rails 5.0. Please migrate your configuration files accordingly.
I hope this answer help you(reader) to understand whats really happens
我希望这个答案可以帮助您(读者)了解真正发生的事情
回答by Ivailo Bardarov
in Rails 5.x the setting is
在 Rails 5.x 中,设置是
config/initializers/assets.rb:
配置/初始化程序/assets.rb:
Rails.application.config.public_file_server.enabled = true
回答by Roy
The following command works for me locally.
以下命令在本地适用于我。
rails server -e production
I got the same error "ActionController::RoutingError (No route matches [GET] "/assets/application.css"" while running "rails s". Even after I precompiled the source, change config precompile true. It still could not load properly.
我在运行“rails s”时遇到了同样的错误“ActionController::RoutingError(没有路由匹配[GET]“/assets/application.css””。即使在我预编译源之后,更改配置预编译为真。它仍然无法加载适当地。
The option "-e production" made those RoutingError disappear.
选项“-e production”使那些 RoutingError 消失了。

