Schienen 4: Assets, die nicht in der Produktion geladen werden


116

Ich versuche, meine App in Produktion zu bringen, und Image- und CSS-Asset-Pfade funktionieren nicht.

Folgendes mache ich gerade:

  • Bildelemente befinden sich in /app/assets/images/image.jpg
  • Stylesheets befinden sich in /app/assets/stylesheets/style.css
  • In meinem Layout verweise ich wie folgt auf die CSS-Datei: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
  • Vor dem Neustart von unicorn starte ich RAILS_ENV=production bundle exec rake assets:precompileund es ist erfolgreich und ich sehe die Fingerabdruckdateien im public/assetsVerzeichnis.

Wenn ich zu meiner Website navigiere, wird der Fehler 404 nicht gefunden für angezeigt mysite.com/stylesheets/styles.css.

Was mache ich falsch?

Update: In meinem Layout sieht es so aus:

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

Die generierte Quelle ist folgende:

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

Anscheinend sucht Rails nicht richtig nach den kompilierten CSS-Dateien. Aber es ist sehr verwirrend, warum es für Javascripts richtig funktioniert (beachten Sie den /assets/****.jsPfad).


Können Sie uns sagen, wie Sie Ihre CSS-Datei laden? Aus Ihrem Fehler geht hervor, dass Sie versuchen, ihn zu verknüpfen, anstatt ihn zu verwenden stylesheet_link_tag.
Kik

1
Gerade oben hinzugefügt. Ich mache<%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" => true %>
emersonthis

Ok, also würde ich zwei Dinge empfehlen: 1. Überprüfen Sie die generierte Quelle, wenn diese Zeile als Pfad zu geschrieben ist, public/assetsund 2. Überprüfen Sie noch einmal, ob irgendwo eine andere Anweisung versucht, diese CSS-Datei zu laden (vermutlich fest codiert)
kik

Ich kann nicht sagen, ob die Verwendung von .erb ein Problem ist, weil ich es nie tue: .home {background: #FFF url(<%= image_path 'hippopotamus.jpg' %>) no-repeat; }Kann tatsächlich im Kettenrad mit ersetzt werden .home {background: #FFF url(image-path('hippopotamus.jpg')) no-repeat; }. Vielleicht können Sie versuchen, ob dies hilft.
Kik

Wollen Sie damit sagen, dass ich diese Referenz in meiner CSS-Datei dynamisch gestalten kann, ohne die Erweiterung .erb hinzuzufügen? Ich habe es geändert, weil ich nicht wollte, dass der Link unterbrochen wird, wenn ich mich im Entwicklungsmodus befinde.
Emersonthis

Antworten:


105

In Schienen 4 müssen Sie die folgenden Änderungen vornehmen:

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

Das funktioniert bei mir. Verwenden Sie den folgenden Befehl, um Assets vorkompilieren zu können

RAILS_ENV=production bundle exec rake assets:precompile

Viel Glück!


11
Ich dachte, wenn Sie config.assets.compile auf true setzen, wird die Leistung in der Produktion beeinträchtigt. auch css.erb? Wer nutzt das? und was ist mit sass und kaffee?
Ahnbizcad

Wenn Kaffee- und Sass-Dateien angefordert werden, werden sie von den Prozessoren verarbeitet, die vom Kaffee-Skript und den Sass-Rails-Edelsteinen bereitgestellt werden, und dann als JavaScript bzw. CSS an den Browser zurückgesendet.
Rameshwar Vyevhare

1
Dieses Problem wurde bereits für Rails 4 behoben und es ist daher nicht erforderlich, Turbokettenrad-Rails3 Gem zu verwenden
Rameshwar Vyevhare

4
Entschuldigung, ich kann die Verbindung zu dem, was Sie gesagt haben, nicht herstellen, um meine Frage zu beantworten.
Ahnbizcad

1
Wenn Sie einen Produktionsserver ausführen, führen Sie normalerweise Rails mit Passagier oder Einhorn oder Puma hinter dem Apache- oder Nginx-Webserver aus. Es ist besser, Apache oder Nginx statische Dateien (js, css, images) und den Rails-Anwendungsserver (puma, unicorn) Rails-Code und -Vorlage bereitstellen zu lassen. Zu diesem Zweck sollten Sie den config.serve_static_filesAlias ​​in Apache und Nginx deaktivieren und konfigurieren assets.
Châu Hồng Lĩnh

85

Ich hatte gerade das gleiche Problem und fand diese Einstellung in config / environment / Production.rb:

# Rails 4:
config.serve_static_assets = false

# Or for Rails 5:
config.public_file_server.enabled = false

Ändern in true es funktioniert. Standardmäßig erwartet Rails, dass Sie Ihren Front-End-Webserver so konfiguriert haben, dass Anforderungen für Dateien aus dem öffentlichen Ordner verarbeitet werden, anstatt sie an die Rails-App weiterzuleiten. Vielleicht haben Sie dies für Ihre Javascript-Dateien getan, aber nicht für Ihre CSS-Stylesheets?

( Siehe Dokumentation zu Rails 5 ). Wie in den Kommentaren erwähnt, können Sie mit Rails 5 nur die RAILS_SERVE_STATIC_FILESUmgebungsvariable festlegen , da die Standardeinstellung ist config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?.


1
DEPRECATION WARNING: Die Konfigurationsoption config.serve_static_assetswurde umbenannt, config.serve_static_filesum ihre Rolle zu verdeutlichen (sie ermöglicht lediglich das Bereitstellen aller Elemente im publicOrdner und steht in keinem Zusammenhang mit der Asset-Pipeline). Der serve_static_assetsAlias ​​wird in Rails 5.0 entfernt. Bitte migrieren Sie Ihre Konfigurationsdateien entsprechend.
Yekta

Früher, als ich mit diesem Problem konfrontiert war, hatte das Ändern dieser Linie es für mich gelöst, aber jetzt stehe ich wieder vor dem Problem (ich weiß nicht, wie ich in diesen Situationen immer wieder lande.) Und das ist nicht genug. Noch mehr Vorschläge, was falsch sein könnte?
IIllIIll

2
Dies sollte die akzeptierte Antwort sein. Obwohl es config.serve_static_filesin Rails 4.2 und config.public_file_server.enabledin Rails 5 ist . @see github.com/heroku/rails_serve_static_assets/blob/master/lib/…
Lucas Nelson

3
Rails 5.0.0.1 config / environment /production.rb enthält, config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?sodass Sie dies für Ihre Umgebung anders einstellen können, ohne den in Ihrem SCM eingecheckten Code zu ändern.
Tobinjim

Um es zu aktivieren: "export RAILS_SERVE_STATIC_FILES =" dann führen Sie "Rails s-e Production" aus. Um es zu deaktivieren: "RAILS_SERVE_STATIC_FILES deaktivieren"
Alfredo Osorio

32

In musste /config/environments/production.rbich Folgendes hinzufügen:

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

Die .js wurde bereits vorkompiliert, aber ich habe sie trotzdem hinzugefügt. Die .css und .css.erb passieren anscheinend nicht automatisch. Das ^[^_]schließt Partials vom Kompilieren aus - es ist ein regulärer Ausdruck.

Es ist ein wenig frustrierend, dass in den Dokumenten eindeutig angegeben ist, dass die Asset-Pipeline standardmäßig aktiviert ist, aber nicht klarstellt, dass dies nur für Javascripts gilt.


Sie müssen styles.css zu config.assets.precompile hinzufügen
Frederick Cheung

23

Ich konnte dieses Problem lösen, indem ich Folgendes änderte: config.assets.compile = falseto
config.assets.compile = truein/config/environments/production.rb

Update (24. Juni 2018) : Diese Methode erstellt eine Sicherheitslücke, wenn die von Ihnen verwendete Version von Sprockets weniger als 2.12.5, 3.7.2 oder 4.0.0.beta8 ist


7
Bedeutet dies nicht, dass Rails die Assets kompiliert, anstatt sie beispielsweise von einem CDN zu laden?
Benjamin Oakes

@BenjaminOakes Ja, und das wollte ich
Yanofsky

2
Dieser Modus benötigt mehr Speicher, ist schlechter als der Standardmodus und wird nicht empfohlen. Verwenden Sie besser einen Nginx-Proxy.
Yekta

16

Für Rails 5 sollten Sie den folgenden Konfigurationscode aktivieren:

config.public_file_server.enabled = true

Standardmäßig wird Rails 5 mit der folgenden Konfigurationszeile geliefert:

config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

Daher müssen Sie die Umgebungsvariable RAILS_SERVE_STATIC_FILESauf true setzen.


1
Für Rails 5 sollte ich hinzufügen, dass ich passenger_env_var RAILS_SERVE_STATIC_FILES true;den Speicherortblock meiner App in meiner Datei nginx.conf festgelegt habe.
Martin Velez

10

Es gibt zwei Dinge, die Sie tun müssen, um die Vermögenswerte in der Produktion zu bedienen:

  1. Kompilieren Sie die Assets vor.
  2. Stellen Sie die Assets auf dem Server dem Browser zur Verfügung.

1) Um die Assets vorkompilieren zu können, haben Sie mehrere Möglichkeiten.

  • Sie können rake assets:precompileauf Ihrem lokalen Computer ausführen , ihn an die Quellcodeverwaltung (git) übergeben und dann das Bereitstellungsprogramm ausführen, z. B. capistrano. Dies ist keine gute Möglichkeit, vorkompilierte Assets an SCM zu übergeben.

  • Sie können eine Rake-Task schreiben, RAILS_ENV=production rake assets:precompiledie jedes Mal auf den Zielservern ausgeführt wird, wenn Sie Ihre Rails-App für die Produktion bereitstellen, bevor Sie den Server neu starten.

Der Code in einer Aufgabe für capistrano sieht folgendermaßen aus:

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) Jetzt haben Sie die Assets auf Produktionsservern und müssen sie dem Browser zur Verfügung stellen.

Auch hier haben Sie mehrere Möglichkeiten.

  • Aktivieren Sie die statische Rails-Datei, die in config / environment / Production.rb bereitgestellt wird

    config.serve_static_assets = true # old
    
    or
    
    config.serve_static_files = true # new

    Wenn Sie Rails zum Bereitstellen statischer Dateien verwenden, wird die Leistung Ihrer Rails-App beeinträchtigt.

  • Konfigurieren Sie nginx (oder Apache) für die Bereitstellung statischer Dateien.

    Zum Beispiel sieht mein Nginx, der für die Arbeit mit Puma konfiguriert wurde, folgendermaßen aus:

    location ~ ^/(assets|images|fonts)/(.*)$ {
        alias /var/www/foster_care/current/public/$1/$2;
        gzip on;
        expires max;
        add_header Cache-Control public;
    }

4

Rails 4 generiert nicht mehr die Version des Assets ohne Fingerabdruck: stylesheets / style.css wird nicht für Sie generiert.

Wenn Sie verwenden, stylesheet_link_tagwird der richtige Link zu Ihrem Stylesheet generiert

Außerdem styles.csssollte in config.assets.precompilewelcher Liste die Dinge vorkompiliert sind


Ich sehe die Fingerabdruckdatei im Verzeichnis / public / assets /. In meinem Layout habe ich <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
Folgendes

Aus irgendeinem Grund zeigt die Produktionsbereitstellung immer noch auf die Originaldateien, wenn ich die Quelle <link data-turbolinks-track="true" href="https://stackoverflow.com/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />ansehe. Aber die Javascript-Dateien sind korrekt! Ich verstehe nicht, warum die gleichen Konfigurationen für .js-Dateien funktionieren, aber nicht für .css.
Emersonthis

Auf Rails 5.0.0.beta3 wird folgende Warnung angezeigt: DEPRECATION WARNING: serve_static_filesist veraltet und wird in Rails 5.1 entfernt. Bitte verwenden Sie public_file_server.enabled = truestattdessen.
GMA

@ Emersonthis Gleiche! Js wird perfekt geladen, aber einige CSS-Dateien erhalten 404. Haben Sie das gelöst?
IvRRimUm

Es ist fast IMMER ein Problem bei der Konfiguration der Asset-Pipeline. Wenn Sie Dateien an einem Speicherort haben, der nicht der Standard ist, ist dies mit ziemlicher Sicherheit das Problem, und Sie müssen die Asset-Pipeline anhand der ersten Antwort darüber informieren.
Emersonthis

3

Ändern Sie Ihre Production.rb-Dateizeile

config.assets.compile = false

in

config.assets.compile = true

und auch hinzufügen

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

warum kompilieren? Wir können nicht davon ausgehen, dass die Produktion während des Betriebs kompiliert wird
James Tan,

1
TUN SIE DAS NIEMALS! Jeder, der config.assets.compile in der Produktion auf true setzt, sollte erschossen werden.
bkunzi01

2

Ich verwende Ubuntu Server 14.04 , Ruby 2.2.1 und Rails 4.2.4. Ich habe ein Bereitstellungsturorial von DigitalOcean befolgt und alles ist gut Wenn ich jedoch zum Browser gehe und die IP-Adresse meines VPS eingebe, wird meine App geladen, aber ohne Stile und Javascript.

Die App läuft mit Unicorn und Nginx . Um dieses Problem zu beheben, habe ich meinen Server über SSH mit meinem Benutzer 'deployer' eingegeben und bin zu meinem App-Pfad '/ home / deployer / apps / blog' gegangen und habe den folgenden Befehl ausgeführt:

RAILS_ENV=production bin/rake assets:precompile

Dann starte ich einfach den VPS neu und das wars! Für mich geht das!

Hoffe, es könnte für jemand anderen nützlich sein!


2

Wenn Vorkompilierung eingestellt ist, brauchen Sie NICHT

config.assets.compile = true

da dies dazu dient, Vermögenswerte live zu dienen.

Unser Problem war, dass wir nur eine geheime Entwicklungsschlüsselbasis eingerichtet hatten config/secrets.yml

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Benötigen Sie Eintrag für Produktionsumgebung


1
Wie in anderen Antworten erwähnt, die Sie benötigen config.assets.precompile = ['*.js', '*.css', '*.css.erb'] und ausführen müssenRAILS_ENV=production bundle exec rake assets:precompile
xxjjnn

1
Dies ermöglicht die Zusammenstellung von Assets während der Produktion, sehr langsam, nicht richtig
James Tan

2

Was Sie nicht tun sollten:

Einige meiner oben genannten Kollegen haben Ihnen empfohlen, dies zu tun:

config.serve_static_assets = true  ## DON”T DO THIS!! 
config.public_file_server.enabled = true ## DON”T DO THIS!!

Die Rails Asset Pipeline sagt über den oben genannten Ansatz:

Dieser Modus benötigt mehr Speicher, ist schlechter als der Standardmodus und wird nicht empfohlen. Siehe hier: ( http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation )

Was du machen solltest:

Kompilieren Sie Ihre Assets vor.

RAILS_ENV=production rake assets:precompile

Sie können das wahrscheinlich mit einer Rechenaufgabe tun.


Warum sollten Sie dem Git Build-Artefakte hinzufügen? Sie können Ihrem Build-Prozess einfach eine Rake-Aufgabe hinzufügen und massiven Gitspam vermeiden (insbesondere, wenn Sie Uglifier und Gzipping haben, was Sie sollten)
Dr.Strangelove

@ Dr.Strangelove Vielen Dank für Ihren Kommentar - darüber weiß ich nicht genug -: Können Sie den Originalbeitrag ausarbeiten / bearbeiten?
BKSpurgeon

1

Der Standard-Matcher zum Kompilieren von Dateien umfasst application.js, application.css und alle Nicht-JS / CSS-Dateien (dies schließt alle Bild-Assets automatisch ein) aus App- / Assets-Ordnern, einschließlich Ihrer Edelsteine:

Wenn Sie andere Manifeste oder einzelne Stylesheets und JavaScript-Dateien einschließen möchten, können Sie diese dem vorkompilierten Array in config / initializers / assets.rb hinzufügen:

Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']

http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets


1

Überprüfen Sie zunächst Ihre Assets. Möglicherweise liegt ein Fehler beim Vorkompilieren der Assets vor.

Führen Sie den folgenden Befehl aus, um Assets in der Produktions-ENV vorkompilieren zu können:

RAILS_ENV=production rake assets:precompile

Wenn ein Fehler angezeigt wird, entfernen Sie diesen zuerst.

Laden Sie im Falle eines Fehlers "undefinierte Variable" diese Variablendatei, bevor Sie sie in einer anderen Datei verwenden.

Beispiel:

@import "variables";
@import "style";

In der Datei application.rb wird die Reihenfolge der Vorkompilierung von Assets festgelegt

Beispiel:

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

1

Ich habe es gefunden:

Die Konfigurationsoption config.serve_static_assetswurde umbenannt config.serve_static_files, um ihre Rolle zu verdeutlichen.

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

Stellen Sie also env RAILS_SERVE_STATIC_FILESoder using ein Nginx, um statische Dateien bereitzustellen. Hinzufügen config.serve_static_assets = truewird weiterhin funktionieren, aber in Zukunft entfernt.


1

Es wird nicht empfohlen, Capistrano Assets vorkompilieren zu lassen, da dies Ewigkeiten und häufig eine Zeitüberschreitung dauern kann. Versuchen Sie, lokale Assets vorkompilieren zu lassen.

Stellen Sie zunächst in config / application.rb ein, führen Sie config.assets.initialize_on_precompile = false dann local aus RAILS_ENV=production bin/rake assets:precompile und fügen Sie diese öffentlichen / Assets zu git hinzu.

und config / environment / development.rb ändern Sie Ihren Asset-Pfad, um die Verwendung vorkompilierter Assets zu vermeiden:

config.assets.prefix = '/dev-assets'

Wenn Sie ein Problem mit der Datenbankverbindung haben, bedeutet dies, dass Sie einen Initialisierer haben, der die Datenbank verwendet. Eine Möglichkeit, dies zu umgehen, besteht darin, eine neue Umgebung durch Duplizieren von Production.rb als möglicherweise Production2 .rb festzulegen und in database.yml die Production2- Umgebung mit der Einstellung Development DB hinzuzufügen . dann mach

RAILS_ENV=production2 bin/rake assets:precompile

Wenn Sie immer noch Probleme mit Assets haben, z. B. ckeditor, fügen Sie die js-Datei in config / initializers / assets.rb hinzu

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


0

Ich kann mich irren, aber diejenigen, die empfehlen, zu ändern

config.assets.compile = true

Der Kommentar in dieser Zeile lautet: # Nicht auf die Assets-Pipeline zurückgreifen, wenn ein vorkompiliertes Asset übersehen wird.

Dies deutet darauf hin, dass Sie das Problem nicht beheben, sondern es umgehen und die Pipeline jedes Mal ausführen, wenn Sie dies auf true setzen. Dies muss sicherlich Ihre Leistung töten und den Zweck der Pipeline zunichte machen?

Ich hatte den gleichen Fehler und er lag an der Anwendung, die in einem Unterordner ausgeführt wurde, von dem Rails nichts wusste.

Meine CSS-Datei befand sich also in home / Unterordner / app / public / .... aber Rails suchte in home / app / public / ...

Versuchen Sie entweder, Ihre App aus dem Unterordner zu verschieben oder Rails mitzuteilen, dass sie sich in einem Unterordner befindet.


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

Dies hat das Problem für mich in der Produktion behoben. Fügen Sie es in die Nginx-Konfiguration ein.


0

Sogar wir hatten das gleiche Problem, wo es RAILS_ENV=production bundle exec rake assets:precompileerfolgreich war, aber die Dinge funktionierten nicht wie erwartet.
Wir fanden, dass Einhorn der Hauptschuldige hier war.

Wie in Ihrem Fall haben auch wir das Einhorn nach dem Kompilieren der Assets neu gestartet. Es wurde festgestellt, dass beim Neustart des Einhorns nur die Arbeitsprozesse neu gestartet werden und nicht der Masterprozess.
Dies ist der Hauptgrund, warum die richtigen Vermögenswerte nicht bedient werden.

Später, nachdem wir Assets kompiliert hatten, stoppten wir Unicorn und starteten es, damit auch der Einhorn-Master-Prozess neu gestartet wurde und die richtigen Assets bereitgestellt wurden.
Das Stoppen und Starten des Einhorns führt zu einer Ausfallzeit von etwa 10 Sekunden im Vergleich zum Neustart des Einhorns. Dies ist die Problemumgehung, die verwendet werden kann, wenn die langfristige Lösung vom Einhorn auf Puma umgestellt wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.