Ich habe einen Produktionsserver mit nginx -> unicorn -> rails. Ich kompiliere Assets vor, wodurch Assets in public/assets abgelegt werden und ein Fingerabdruck (Hash) an den Dateinamen angehängt wird. Wenn jedoch eine Webseite angefordert wird, haben Verweise auf application.css- und application.js-Assets den falschen Fingerabdruck. Beispielsweise generiert der Rails-Helfer stylesheet_link_tag einen Dateinamen, der in public/assets auf dem Server nicht vorhanden ist, da der angeforderte Fingerabdruck nicht mit dem vorkompilierten übereinstimmt. Bild-Assets funktionieren einwandfrei (Fingerabdrücke stimmen überein).
Zur Fehlerbehebung habe ich Assets auf meinem lokalen Computer vorkompiliert und der Fingerabdruck stimmt mit dem vorkompilierten Fingerabdruck auf meinem Server überein. Außerdem funktioniert alles, wenn ich es lokal mit Webrick im Produktionsmodus ausführe. Dann habe ich versucht, Webrick auf meinem Server auszuführen, was funktionierte, was mich glauben ließ, dass Unicorn die Ursache des Problems ist.
Ich habe dieses Problem gelöst, indem ich Unicorn mit der Option --no-default-middleware (oder -N) gestartet habe. Dadurch verhält sich Unicorn in Bezug auf vorkompilierte Assets wie erwartet. Meines Wissens nach weist dies Unicorn an, einen Standardsatz von Rack-Middleware nicht zu laden, den es sonst laden würde. Ich verstehe jedoch nicht wirklich, warum dies das Problem löst oder was überhaupt schief läuft. Was ist los?
Einige Besonderheiten: Ubuntu 12.04, Rails 4.0.1, Ruby 2.1.0, Bootstrap 3.0 mit einem Drittanbieter-Design
Aktualisieren:
Der Grund, warum ich nicht glaube, dass dies ein nginx-Problem ist, ist, dass, wenn ich die Seite von einem Browser aus anfordere und dann die Quelle ansehe, der Dateiname für die Datei application.css einen Fingerabdruck hat, sodass er tatsächlich wie application-3855b1928b94aa5bff5e1dac1aa56882.css aussieht. Dies stimmt nicht mit dem echten Fingerabdruck der Datei auf meinem Server überein. Ich bin überzeugt, dass der Fingerabdruck auf dem Server korrekt ist, da ich denselben Fingerabdruck auf meiner lokalen Entwicklungsmaschine erhalte. Der Client lädt also die Webseite und fragt dann den Server nach der CSS-Datei ... nginx erhält diese Anforderung, kann die CSS-Datei jedoch nicht finden, da sie tatsächlich nicht vorhanden ist. Daher verhält sich nginx wie erwartet.
Der Fingerabdruck wird zweimal generiert: Einmal, wenn ich Assets vorkompiliere, was (ziemlich sicher) korrekt funktioniert und ohne Einbeziehung von Unicorn geschieht. Und ein zweites Mal, wenn Rails im Kontext eines Unicorn-Workers den Stylesheet_Link_Tag-Helfer sieht und den Fingerabdruck spontan berechnet (ich glaube, das ist es, was es tut), was aus irgendeinem Grund einen falschen Fingerabdruck generiert. Derselbe Vorgang passiert, wenn ich Unicorn auf genau demselben Server durch Webrick ersetze, aber in diesem Fall stimmen die Fingerabdrücke überein. Wenn ich Unicorn mit dem Flag -N starte, stimmen die Fingerabdrücke überein, aber ich weiß nicht, warum das einen Unterschied macht, und ich weiß nicht, warum scheinbar niemand sonst dies tun muss.
Antwort1
In Rails 4 müssen Sie die folgenden Änderungen vornehmen
config.assets.compile = true
config.assets.precompile = ['*.js', '*.css', '*.css.erb']
Bei mir funktioniert das. Verwenden Sie den folgenden Befehl, um Assets vorab zu kompilieren
RAILS_ENV=production bundle exec rake assets:precompile
aushttps://stackoverflow.com/questions/18700219/rails-4-assets-not-loading-in-production