2013-08-23 7 views
7

Meine Produktionsbereitstellungen dauern aufgrund der Zeit, die für die Installation von nokogiri gem (1.6.0) benötigt wird, ein paar zusätzliche Minuten. Ich verstehe das, weil die Installation des Gems die native Erweiterungserstellung auslöst.Überspringen der nativen Extension-Neukompilierung bei der nachfolgenden Paket-Installation

Bitte beachte, dass ich mein Bündel verpackt haben und überprüft es in DVCS

bundle package 

Gibt es eine Möglichkeit Neuübersetzung von nativen Erweiterungen zu vermeiden, wenn nichts anderes geändert hat, so dass Implementierungen schneller sind?

Update:

verwende ich Opscode Chef (Koch-Solo zu sein) zu implementieren

Umgebung: Ubuntu 12.04LTS 64bit Ruby-193-P448

+0

Ein 'Bündel install' in der Regel für mich gearbeitet Edelsteine ​​überspringt die Bündler bereits Anforderungen passende findet. Was verwenden Sie zum Bereitstellen? –

+0

@NeilSlater Ich benutze Chef, um bereitzustellen. – Litmus

+0

Ich habe keine Antwort für alle nativen Erweiterungen, aber haben Sie versucht, NOKOGIRI_USE_SYSTEM_LIBRARIES = true hinzuzufügen? – zrl3dx

Antwort

4

fand ich ein Weg, dies zu tun. Hier ist die Erklärung:

Bundler, installiert standardmäßig Edelsteine ​​in einen Ordner, auf den die Umgebungsvariable BUNDLE_PATH zeigt. Der Standardwert von BUNDLE_PATH ist vendor/bundle. Daher werden alle Edelsteine ​​im Ordner /vendor/bundle installiert, der zufällig ein privater Ordner ist (für jede Version der Rails-Anwendung). Wenn eine neue Version der Rails-Anwendung installiert wird, ist vendor/bundle nicht vorhanden. Daher installiert/prepliziert Bundler jedes Juwel. Es nimmt die Edelsteine ​​von vendor/cache auf, was eine gute Einsparung gegenüber dem Herunterladen derselben von rubygems.org ist, aber es kann trotzdem die Kompilierung von nativen Erweiterungen nicht vermeiden.

Wir können dies überschreiben, indem wir --path /shared/path an die bundle install-Befehlszeile übergeben. Dadurch wird sichergestellt, dass die Edelsteine ​​immer in /shared/path installiert sind, auf das alle Versionen (der Rails-Anwendung) zugreifen können.

Mit diesem Ansatz wird Bundler nicht versuchen, ein Juwel neu zu installieren/neu zu kompilieren, da es das gleiche bereits installiert findet.

so ist dies die magische Befehl,

bundle install --local --deployment --path /shared/bundle --without development test 
+0

Seien Sie vorsichtig, dass Sie eines Tages eine App in der Vergangenheit haben, die den neuesten Edelstein nicht verwenden kann. Wenn das passiert, könntest du es sehr bereuen, dass du deine Edelsteine ​​nicht verkauft hast. –

+1

Nicht wahr. In der Produktion möchte ich, dass die App nur die Edelsteine ​​verwendet, die mit 'Gemfile.lock' gesperrt sind. Gem-Upgrades finden in der Entwicklung statt (mit 'bundle veraltet' und' bundle update'). Da ich 'bundle package' verwende, werden diese aktualisierten Edelsteine ​​in' vendor/cache' gespeichert.Und in der Produktion, wenn ich 'bundle install - deployment 'starte, werden die neuen Edelsteine ​​von' vendor/cache' übernommen und in dem Pfad installiert, der wie oben beschrieben mit der Option 'path angegeben wurde. – Litmus

+0

Dies ist so nützlich und absolut sicher, dass ich mich wundere, warum dies nicht das Standardverhalten bei der Verwendung von "--deployment" ist! Nokogiri ist der schlimmste Alptraum jedes Deployers. –