2013-08-23 13 views
7

Moje wdrożenia produkcyjne trwają kilka dodatkowych minut ze względu na czas potrzebny na zainstalowanie gem nokogiri (1.6.0). Rozumiem, że dzieje się tak dlatego, że po zainstalowaniu klejnotu uruchamiana jest natywna kompilacja rozszerzeń.Pomijanie rekompilacji natywnych rozszerzeń w następnej instalacji pakietu

Zauważ, że ja pakuje moją paczkę i sprawdzić go w DVCS

bundle package 

Czy istnieje sposób, aby uniknąć ponownej kompilacji natywnych rozszerzeniach jeśli nic innego nie uległa zmianie, tak że wdrożenia są szybsze?

Aktualizacja:

używam Opscode Chef wdrożyć (kucharz-solowy być specyficzne)

środowisko jest: Ubuntu 12.04LTS 64bit Ruby 193-P448

+0

'pakiet install' zwykle pomija klejnotów, które Bundler znaleziska już dopasowania wymagań. Czego używasz do wdrożenia? –

+0

@NeilSlater Używam szefa kuchni do wdrożenia. – Litmus

+0

Nie mam odpowiedzi dla wszystkich rozszerzeń natywnych, ale czy próbowałeś dodać 'NOKOGIRI_USE_SYSTEM_LIBRARIES = true'? – zrl3dx

Odpowiedz

4

znalazłem sposób, aby to zrobić. Oto wyjaśnienie:

Bundler, domyślnie instaluje klejnoty w folderze wskazanym przez zmienną środowiskową BUNDLE_PATH. Domyślna wartość BUNDLE_PATH to vendor/bundle. Stąd wszystkie klejnoty są instalowane w folderze /vendor/bundle, który jest folderem prywatnym (dla każdej wersji aplikacji Rails). Po zainstalowaniu nowej wersji aplikacji Railsowej nie istnieje vendor/bundle. Stąd Bundler instaluje/prekompiluje każdy klejnot. Pobiera klejnoty z vendor/cache, co jest dobrym oszczędzaniem na pobieranie tego samego z rubygems.org, ale nadal nie może uniknąć kompilacji rozszerzeń natywnych.

Możemy to zmienić, przekazując --path /shared/path do linii poleceń bundle install. Zapewni to, że klejnoty są zawsze instalowane w wersji /shared/path, która jest dostępna dla wszystkich wersji (aplikacji Rails).

Dzięki temu podejściu bundler nie spróbuje ponownie zainstalować/ponownie skompilować brylantu, ponieważ znajdzie to samo, co już zostało zainstalowane.

tak, to jest magia komenda że pracował dla mnie

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

Uważaj, pewnego dnia możesz mieć aplikację zablokowaną w przeszłości, która nie może użyć najnowszego klejnotu. Kiedy to nastąpi, możesz bardzo żałować, że nie sprzedałeś swoich klejnotów. –

+1

Nieprawda. W produkcji chcę, aby aplikacja używała tylko klejnotów, które są zablokowane przy użyciu 'Gemfile.lock'. Aktualizacje klejnotów zdarzają się w fazie rozwoju (przy użyciu 'bundle outdated' i' bundle update'). Ponieważ używam 'bundle package', te uaktualnione klejnoty są przechowywane w' vendor/cache'.I w produkcji, kiedy uruchamiam 'bundle install --deployment' nowe klejnoty są pobierane z' vendor/cache' i instalowane w ścieżce określonej przez opcję '--path', jak wyjaśniono powyżej. – Litmus

+0

Jest to tak przydatne i całkowicie bezpieczne, że zastanawiam się, dlaczego nie jest to domyślne zachowanie przy użyciu '--deployment'! Nokogiri to najgorszy koszmar każdego deployera. –