Подтвердить что ты не робот

Приложение Rails не обслуживает активы в производственной среде

Мое приложение отлично работает при запуске в среде разработки. В процессе производства (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"):

Раздел заголовка из источника html в рабочей среде:

<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>

В разработке env, с другой стороны, раздел главы выглядит следующим образом:

<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>

Приложение не использует базу данных, поэтому я отключил ActiveRecord. Фрагменты конфигурационных файлов:

application.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

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:

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.

Приносим извинения за размещение такой информации. Я чувствовал, что информация может быть актуальной.

p.s. У меня есть только наполовину испеченное знание рельсов, так что несите меня. Благодаря ~

4b9b3361

Ответ 1

При локальном тестировании вашей производственной среды вам необходимо скомпилировать активы локально. Просто запустите следующую команду:

RAILS_ENV=production bundle exec rake assets:precompile

Он будет генерировать все активы под public/assets.

Затем вам нужно указать Rails для обслуживания самих активов. Серверное программное обеспечение (например, Nginx или Apache) делает это для вас в таких средах, как Heroku, но локально вы должны позволить Rails сделать это. Измените это в production.rb:

config.serve_static_assets = true

Но прежде чем нажимать код на производство, убедитесь, что вы вернели его до false!

Ответ 2

Это похоже на проблему, с которой я столкнулся.

Я нашел блог, в котором говорится, что это ошибка в конвейере ресурсов Rails 4.0.0, и она необъяснимо смягчается установкой...

config.assets.compile = true

... в config/environments/production.rb

Помимо того, что каким-то образом включается конвейер активов в фактическую работу, эта настройка включит живую компиляцию активов. Как правило, это плохо для производительности в производственном процессе, но если вы все же вручную прекомпилируете ресурсы при развертывании, с

rake assets:precompile

... живая компиляция никогда не должна происходить (потому что необходимые ресурсы уже были предварительно скомпилированы).

Надеюсь, это поможет :)

Ответ 3

Как уже отмечалось, config.serve_static_assets устарел и заменен на config.serve_static_files. Если вы рассмотрите config/environments/production.rb для Rails-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?

Импликация, заключающаяся в том, что настройка и экспорт (в BASH), переменная среды export RAILS_SERVE_STATIC_FILES="to any value whatsoever" в сеансе перед запуском rails s -e production даст желаемый результат при локальном тестировании, а также позволит избежать необходимости перекодировать production.rb перед нажатием на хост-узел.

Ответ 4

В production.rb измените настройку:

рельсы 3.x

config.serve_static_assets = true

рельсы 4.x

config.serve_static_files = true

Ответ 5

Проверьте файл следующим образом:

public/assets/.sprockets-manifest-3f7771d777ceb581d754e4fad88aa69c.json

Если вы нажимаете предварительно скомпилированные активы на производственный сервер, есть вероятность, что вы предотвращаете скрытые "точечные" файлы, которые будут выталкиваться, и этот важный файл не будет вносить в производство.

В моей среде мне нужно предварительно скомпоновать активы в среде интеграции и подтолкнуть их к производству, чтобы не было необходимости компилировать активы на производственной машине. Я ошибочно блокировал все скрытые файлы от толкания на производственную машину.

Чтобы узнать, работает ли этот ответ для вас, проверьте созданный источник HTML в браузере с производственного сервера, чтобы узнать, был ли создан путь к ресурсам. Если вы видите тэг script следующим образом:

<script data-turbolinks-track="true" src="/javascripts/application.js"></script>

проверить атрибут src. Он должен начинаться с /assets/javascript. В этом случае он начинается с /javascript, который указывает, что Rails не считает, что какое-либо из активов было предварительно скомпилировано.

Я исправил это, обновив мой push-to production (в настоящее время rsync), гарантируя, что я выталкиваю файл .sprockets-manifest* после предварительной компиляции на моем сервере интеграции.

Кроме того, я использую автономный Пассажир как мой тестовый сервер интеграции, а не Webrick, поскольку он обрабатывает более реалистичную службу статических файлов.

Ответ 6

Я думаю, что Rails 4.x вам нужно предварительно скомпилировать активы для производства или использовать config.assets.compile даже при необходимости.

Поведение Rails по умолчанию для производственной среды - "Не отступать от конвейера активов, если укомплектован предварительно скомпилированный актив". Итак, не надо. Использовать не для компиляции

config.assets.compile = false

Если вы используете эту опцию, вам не нужно использовать:

config.serve_static_files = true

Потому что, если актив не был предварительно скомпилирован, Rails будет компилироваться перед подачей запроса.

Но если вы предварительно скомпилируете активы до производства, вам не нужен config.assets.compile = true, но вам нужно config.serve_static_files = true для запросов на обслуживание Rails, если у вас нет http_server для обслуживания предварительно скомпилированных активов.

Установка 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.

Я надеюсь, что этот ответ поможет вам (читателю) понять, что происходит на самом деле

Ответ 7

Следующая команда работает для меня локально.

rails server -e production

Я получил ту же ошибку "ActionController:: RoutingError (Нет маршрутов соответствует [GET]" /assets/application.css "при запуске" rails s". Даже после того, как я предварительно скомпилировал источник, измените конфигурацию precompile true. не удалось загрузить должным образом.

Опция "-e production" заставила эти RoutingError исчезнуть.