web-dev-qa-db-fra.com

Application Rails ne servant pas d'actifs dans l'environnement de production

Mon application fonctionne correctement lorsqu'elle est exécutée dans un environnement de développement. En production (Rails server -e production), le navigateur ne peut pas accéder aux fichiers css et js et des messages tels que:

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"):

La section head de la source HTML en environnement de production:

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

En développement, par contre, la section head ressemble à ceci:

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

L'application n'utilise pas de base de données, j'ai donc désactivé ActiveRecord. Extraits des fichiers de configuration:

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.

Je m'excuse d'avoir posté tant d'informations. J'ai senti que l'information pourrait être pertinente. 

p.s. Je connais à peine la connaissance de Rails, alors supporte-moi. Merci ~

41
septerr

Lorsque vous testez localement votre environnement de production, vous devez compiler les ressources localement. Il suffit de lancer la commande ci-dessous:

Rails_ENV=production bundle exec rake assets:precompile

Il générera tous les actifs sous public/assets

Ensuite, vous devez dire à Rails de servir les actifs eux-mêmes. Le logiciel serveur (par exemple Nginx ou Apache) le fait pour vous dans des environnements tels que Heroku, mais localement, vous devez laisser Rails le faire. Changez cela dans votre production.rb:

config.serve_static_assets = true

Mais assurez-vous de le redéfinir sur false avant de mettre votre code en production!

69
jibai31

Comme indiqué précédemment, config.serve_static_assets est obsolète et remplacé par config.serve_static_files. Si on examine config/environments/production.rb pour Rails-4.2, alors on trouve ceci:

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

L'implication étant que la définition et l'exportation (sous BASH) de la variable d'environnement export Rails_SERVE_STATIC_FILES="to any value whatsoever" dans une session antérieure à l'exécution de Rails s -e production donneront le résultat souhaité lors du test local, et éviteront également d'avoir à mémoriser production.rb avant de transmettre à l'hôte de production.

10
James B. Byrne

Dans production.rb changez le réglage:

Rails 3.x

config.serve_static_assets = true

Rails 4.x

config.serve_static_files = true
6
Chris Aitchison

Recherchez un fichier comme celui-ci:

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

Si vous transférez des ressources précompilées sur un serveur de production, il est possible que vous empêchiez le transfert de fichiers «points» cachés et que ce fichier essentiel ne sera pas mis en production. 

Dans mon environnement, j'ai besoin de précompiler des actifs dans un environnement d'intégration et de les pousser en production afin qu'il ne soit pas nécessaire de les compiler sur la machine de production. Je bloquais par erreur tous les fichiers cachés d'être envoyés à la machine de production. 

Pour voir si cette réponse vous convient, vérifiez votre source HTML générée dans un navigateur à partir du serveur de production pour voir si le chemin des ressources a été généré. Si vous voyez votre balise de script comme ceci:

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

vérifiez l'attribut src. Il devrait commencer par /assets/javascript. Dans ce cas, il commence par /javascript, ce qui indique que Rails ne pense pas qu’un des actifs ait été précompilé.

J'ai corrigé ce problème en mettant à jour mon Push en production (actuellement rsync), en m'assurant que je pousse le fichier .sprockets-manifest* après la précompilation sur mon serveur d'intégration.

De plus, j'utilise Passenger en tant que serveur de test d'intégration, plutôt que Webrick, car il gère des serveurs plus réalistes de fichiers statiques.

4
Phil

Je pense que pour Rails 4.x, vous devez précompiler des actifs pour la production ou utiliser config.assets.compile, même les deux si nécessaire.

Le comportement par défaut de Rails pour l'environnement de production est le suivant:"Ne pas recourir au pipeline d'actifs si un actif précompilé est manquant."Alors, ne le faites pas… .. Utilisez pour ne pas compi

config.assets.compile = false

Si vous utilisez cette option, vous n'avez pas besoin d'utiliser:

config.serve_static_files = true

Parce que si l'actif n'était pas précompilé, Rails compilera avant la demande de service.

Mais si vous pré-compilez les actifs avant la production, vous n'avez pas besoin de config.assets.compile = true, mais vous avez besoin de config.serve_static_files = true pour les demandes de service Rails si vous n'avez pas http_server pour servir les actifs précompilés.

Le paramètre config.serve_static_assets est obsolète.

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.

J'espère que cette réponse vous aidera (lecteur) à comprendre ce qui se passe réellement

3
Rui Andrada

dans Rails 5.x, le réglage est

config/initializers/assets.rb:

Rails.application.config.public_file_server.enabled = true

https://edgeguides.rubyonrails.org/configuring.html

1
Ivailo Bardarov

La commande suivante fonctionne pour moi localement.

Rails server -e production

J'ai la même erreur "ActionController :: RoutingError (Aucune route ne correspond à [GET]" /assets/application.css "" pendant l'exécution de "Rails s". Même après avoir précompilé le source, modifiez config prececile true. Il n'a toujours pas pu charger. correctement. 

L'option "-e production" a fait disparaître ces erreurs de routage. 

0
Roy