Szyny 4: zasoby nie są ładowane w produkcji


116

Próbuję wprowadzić moją aplikację do produkcji, a ścieżki zasobów obrazu i css nie działają.

Oto, co obecnie robię:

  • Zasoby graficzne znajdują się w /app/assets/images/image.jpg
  • Arkusze stylów znajdują się w /app/assets/stylesheets/style.css
  • W moim układzie odwołuję się do pliku css w następujący sposób: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
  • Przed ponownym uruchomieniem jednorożca uruchamiam RAILS_ENV=production bundle exec rake assets:precompilei się udaje i widzę pliki z odciskami palców w public/assetskatalogu.

Kiedy przeglądam moją witrynę, otrzymuję błąd 404 nie znaleziono dla adresu mysite.com/stylesheets/styles.css.

Co ja robię źle?

Aktualizacja: W moim układzie wygląda to tak:

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

Generowane źródło jest następujące:

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

Wygląda na to, że Railsy nie szukają poprawnie skompilowanych plików css. Ale to bardzo mylące, dlaczego działa poprawnie dla skryptów javascript (zwróć uwagę na /assets/****.jsścieżkę).


Czy możesz nam powiedzieć, jak ładujesz swój plik css? Wygląda na to, że z twojego błędu próbujesz połączyć go na stałe, zamiast używać stylesheet_link_tag.
— kik

1
Właśnie dodane powyżej. Robię<%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" => true %>
— emersonthis

Ok, więc zaleciłbym dwie rzeczy: 1. sprawdź wygenerowane źródło, czy ta linia jest zapisana jako ścieżka do public/assetsi 2. sprawdź, czy nie ma gdzieś innej instrukcji próbującej załadować ten plik css (prawdopodobnie zakodowany na
— stałe

Nie mogę powiedzieć, czy używanie .erb jest problemem, ponieważ nigdy tego nie robię: w .home {background: #FFF url(<%= image_path 'hippopotamus.jpg' %>) no-repeat; }rzeczywistości można go wymienić w zębatce na .home {background: #FFF url(image-path('hippopotamus.jpg')) no-repeat; }. Może spróbuj, jeśli to pomoże.
— kik

Czy chcesz powiedzieć, że mogę wprowadzić to odniesienie do mojego pliku css jako dynamiczne bez dodawania rozszerzenia .erb? Zmieniłem to, ponieważ nie chciałem, aby łącze zrywało się, gdy jestem w trybie programowania.
— emersonthis

Odpowiedzi:


105

W szynach 4 musisz wprowadzić poniższe zmiany:

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

To działa ze mną. użyj następującego polecenia, aby wstępnie skompilować zasoby

RAILS_ENV=production bundle exec rake assets:precompile

Powodzenia!


11
Myślałem, że ustawienie config.assets.compile na true zabije wydajność w środowisku produkcyjnym. także css.erb? kto tego używa? a co z sassem i kawą?
— ahnbizcad

gdy żądane są pliki coffee i sass, są one przetwarzane przez procesory dostarczone przez klejnoty coffee-script i sass-rails, a następnie wysyłane z powrotem do przeglądarki jako odpowiednio JavaScript i CSS.
— Rameshwar Vyevhare

1
Ten problem został już rozwiązany dla Rails 4, więc nie ma potrzeby używania turbo-sprocket-rails3 gem
— Rameshwar Vyevhare

4
Przepraszam, nie jestem w stanie powiązać tego, co powiedziałeś, aby odpowiedzieć na moje pytanie.
— ahnbizcad

1
Zwykle, gdy uruchamiasz serwer produkcyjny, będziesz uruchamiał Railsy z pasażerem, jednorożcem lub pumą za serwerem Apache lub nginx. Lepiej jest pozwolić Apache lub nginxowi obsługiwać pliki statyczne (js, css, obrazy), a serwer aplikacji Rails (puma, unicorn) obsługiwać kod i szablon Railsów. Aby to zrobić, należy wyłączyć config.serve_static_filesi skonfigurować alias w Apache i nginx assets.
— Châu Hồng Lĩnh

85

Właśnie miałem ten sam problem i znalazłem to ustawienie w config / environment / production.rb:

# Rails 4:
config.serve_static_assets = false

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

Zmieniam to na true działało. Wygląda na to, że domyślnie Railsy oczekują, że skonfigurujesz swój serwer frontonu do obsługi żądań plików z folderu publicznego zamiast przekazywania ich do aplikacji Rails. Być może zrobiłeś to dla swoich plików javascript, ale nie dla arkuszy stylów CSS?

( Zobacz dokumentację Rails 5 ). Jak zauważono w komentarzach, w Railsach 5 możesz po prostu ustawić RAILS_SERVE_STATIC_FILESzmienną środowiskową, ponieważ domyślnym ustawieniem jest config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?.


1
OSTRZEŻENIE O DEPRECATION: Zmieniono config.serve_static_assetsnazwę opcji konfiguracji na, config.serve_static_filesaby wyjaśnić jej rolę (umożliwia jedynie obsługę wszystkiego w publicfolderze i nie jest związana z potokiem zasobów). serve_static_assetsPs zostaną usunięte w szynach 5,0. Przeprowadź odpowiednią migrację plików konfiguracyjnych.
— yekta

Wcześniej, kiedy stawiałem czoła temu problemowi, zmiana tej linii rozwiązała go za mnie, ale teraz mam do czynienia z tym ponownie (nie wiem, jak ciągle kończę w takich sytuacjach) i to nie wystarczy. Masz więcej sugestii, co może być nie tak?
— IIIIIll

2
To powinna być akceptowana odpowiedź. Chociaż jest config.serve_static_filesw Rails 4.2 i config.public_file_server.enabledRails 5 . @see github.com/heroku/rails_serve_static_assets/blob/master/lib/…
— Lucas Nelson

3
Rails 5.0.0.1 config / environment / production.rb zawiera, config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?więc możesz ustawić to inaczej dla swojego środowiska bez zmiany kodu, który jest wpisany do SCM.
— tobinjim

Aby to włączyć: "eksportuj RAILS_SERVE_STATIC_FILES =" następnie uruchom "rails s -e production" Aby to wyłączyć: "unset RAILS_SERVE_STATIC_FILES"
— Alfredo Osorio

32

W /config/environments/production.rbmusiałem to dodać:

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

.Js był już prekompilowany, ale i tak go dodałem. Najwyraźniej pliki .css i .css.erb nie pojawiają się automatycznie. W ^[^_]wyklucza partials z kompilowane - to wyrażenie regularne.

To trochę frustrujące, że dokumentacja jasno stwierdza, że ​​potok aktywów jest domyślnie włączony, ale nie wyjaśnia faktu, że dotyczy to tylko skryptów JavaScript.


Musisz dodać styles.css do config.assets.precompile
— Frederick Cheung

23

Udało mi się rozwiązać ten problem poprzez zmianę: config.assets.compile = falsedo
config.assets.compile = trueIN/config/environments/production.rb

Aktualizacja (24 czerwca 2018 r.) : Ta metoda tworzy lukę w zabezpieczeniach, jeśli używana wersja Sprockets jest niższa niż 2.12.5, 3.7.2 lub 4.0.0.beta8


7
Czy to nie oznacza, że ​​Railsy kompilują zasoby zamiast, powiedzmy, ładować je z CDN?
— Benjamin Oakes

@BenjaminOakes Tak, i tego właśnie chciałem
— Yanofsky

2
Ten tryb zużywa więcej pamięci, działa gorzej niż domyślny i nie jest zalecany. Lepiej jest użyć proxy Nginx.
— yekta

16

Dla Rails 5 powinieneś włączyć następujący kod konfiguracyjny:

config.public_file_server.enabled = true

Domyślnie Rails 5 są dostarczane z następującą linią konfiguracji:

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

Dlatego musisz ustawić zmienną środowiskową RAILS_SERVE_STATIC_FILESna true.


1
W przypadku Rails 5 powinienem dodać, ustawiam passenger_env_var RAILS_SERVE_STATIC_FILES true;w bloku lokalizacji mojej aplikacji w moim pliku nginx.conf.
— Martin Velez,

10

Aby obsłużyć zasoby w produkcji, musisz wykonać 2 rzeczy:

  1. Wstępnie skompiluj zasoby.
  2. Przekaż zasoby z serwera do przeglądarki.

1) Aby wstępnie skompilować zasoby, masz kilka możliwości.

  • Możesz uruchomić rake assets:precompilena komputerze lokalnym, zatwierdzić go do kontroli kodu źródłowego (git), a następnie uruchomić program wdrożeniowy, na przykład capistrano. To nie jest dobry sposób przekazywania wstępnie skompilowanych zasobów do SCM.

  • Możesz napisać zadanie rake, które będzie uruchamiane RAILS_ENV=production rake assets:precompilena serwerach docelowych za każdym razem, gdy wdrażasz aplikację Rails w środowisku produkcyjnym, zanim zrestartujesz serwer.

Kod w zadaniu dla Capistrano będzie wyglądał podobnie do tego:

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) Teraz masz zasoby na serwerach produkcyjnych, musisz je udostępnić przeglądarce.

Ponownie masz kilka możliwości.

  • Włącz obsługę plików statycznych Railsów w config / environment / production.rb

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

    Używanie Railsów do obsługi plików statycznych może obniżyć wydajność Twojej aplikacji Railsowej.

  • Skonfiguruj nginx (lub Apache) do obsługi plików statycznych.

    Na przykład mój nginx, który został skonfigurowany do pracy z Pumą, wygląda następująco:

    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 nie generuje już wersji zasobu bez odcisku palca: arkusze stylów / style.css nie będą generowane dla Ciebie.

Jeśli użyjesz, stylesheet_link_tagzostanie wygenerowany poprawny link do twojego arkusza stylów

Dodatkowo styles.csspowinno być w config.assets.precompilektórym jest lista rzeczy, które są prekompilowane


Widzę plik z odciskami palców w katalogu / public / asset /. W moim układzie mam to: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>Czy to jest niepoprawne? '
— emersonthis,

Z jakiegoś powodu wdrożenie produkcyjne nadal wskazuje oryginalne pliki, gdy przeglądam źródło. <link data-turbolinks-track="true" href="https://stackoverflow.com/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />Ale pliki javascript są poprawne! Nie rozumiem, dlaczego te same konfiguracje działają dla plików .js, ale nie .css.
— emersonthis

Na Railsach 5.0.0.beta3 pojawia się ostrzeżenie: OSTRZEŻENIE O WYCOFANIU: serve_static_filesjest przestarzałe i zostanie usunięte w Railsach 5.1. Użyj public_file_server.enabled = truezamiast tego.
— GMA

@emersonthis Same! Js ładuje się idealnie, ale niektóre pliki css otrzymują 404. Czy rozwiązałeś to?
— IvRRimUm

To prawie ZAWSZE problem z konfiguracją potoku zasobów. Jeśli masz pliki w dowolnej lokalizacji, która nie jest domyślna, to prawie na pewno problem i musisz powiedzieć o tym potokowi zasobów, używając czegoś podobnego do pierwszej odpowiedzi.
— emersonthis

3

zmień linię pliku Production.rb

config.assets.compile = false

w

config.assets.compile = true

a także dodaj

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

dlaczego kompilować? nie powinniśmy kompilować na produkcji podczas jej działania
— James Tan

1
NIGDY TEGO NIE ROBIĆ! Każdy, kto ustawi config.assets.compile na true w środowisku produkcyjnym, powinien zostać nakręcony.
— bkunzi01

2

Używam Ubuntu Server 14.04 , Ruby 2.2.1 i Rails 4.2.4. Śledziłem proces wdrażania z DigitalOcean i wszystko poszło dobrze, ale kiedy idę do przeglądarki i wprowadzam adres IP mojego VPS, moja aplikacja jest ładowana, ale bez style i javascript.

Aplikacja działa z Unicorn i Nginx . Aby rozwiązać ten problem, wszedłem na mój serwer za pomocą SSH z moim użytkownikiem „deployer” i przeszedłem do ścieżki mojej aplikacji, czyli „/ home / deployer / apps / blog”, i uruchomiłem następujące polecenie:

RAILS_ENV=production bin/rake assets:precompile

Następnie ponownie uruchamiam VPS i to wszystko! Mi to pasuje!

Mam nadzieję, że może to być przydatne dla kogoś innego!


2

Jeśli ustawiono prekompilację, NIE potrzebujesz

config.assets.compile = true

ponieważ ma to służyć aktywnym zasobom.

Nasz problem polegał na tym, że mieliśmy tylko ustawioną bazę tajnych kluczy programistycznych config/secrets.yml

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Potrzebujesz wejścia do środowiska produkcyjnego


1
jak wspomniano w innych odpowiedziach, których potrzebujesz config.assets.precompile = ['*.js', '*.css', '*.css.erb'] i uruchomićRAILS_ENV=production bundle exec rake assets:precompile
— xxjjnn

1
umożliwia to kompilację zasobów podczas produkcji na żywo, bardzo wolno, źle
— James Tan

2

Czego NIE POWINIENEŚ robić:

Niektórzy z moich kolegów powyżej zalecili ci to zrobić:

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

Potok aktywów kolejowych mówi o powyższym podejściu:

Ten tryb zużywa więcej pamięci, działa gorzej niż domyślny i nie jest zalecany. Zobacz tutaj: ( http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation )

Co powinieneś zrobić:

Prekompiluj swoje zasoby.

RAILS_ENV=production rake assets:precompile

Prawdopodobnie możesz to zrobić za pomocą zadania prowizji.


Po co jednak dodawać artefakty kompilacji do gita? Możesz po prostu dodać zadanie rake do procesu kompilacji i uniknąć masowego gitspamu (szczególnie jeśli masz uglifier i gzipping, co powinieneś)
— Dr Strangelove

@ Dr. Strangelove Dziękuję za komentarz - nie wiem wystarczająco dużo na ten temat -: czy możesz rozwinąć / edytować oryginalny post?
— BKSpurgeon

1

Domyślny element dopasowujący do kompilowania plików obejmuje application.js, application.css i wszystkie pliki inne niż JS / CSS (automatycznie obejmie to wszystkie zasoby graficzne) z folderów aplikacji / zasobów, w tym klejnotów:

Jeśli masz inne manifesty lub indywidualne arkusze stylów i pliki JavaScript do dołączenia, możesz dodać je do tablicy prekompilacji w config / initializers / asset.rb:

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

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


1

Przede wszystkim sprawdź swoje zasoby, być może wystąpił błąd podczas wstępnej kompilacji zasobów.

Aby wstępnie skompilować zasoby w środowisku produkcyjnym, ENV uruchom to polecenie:

RAILS_ENV=production rake assets:precompile

Jeśli wyświetla błąd, najpierw go usuń,

W przypadku błędu „niezdefiniowana zmienna”, załaduj ten plik zmiennej przed użyciem go w innym pliku.

przykład:

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

w pliku application.rb ustaw sekwencję wstępnej kompilacji aktywów

przykład:

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

Znajdź to:

Nazwa opcji konfiguracji config.serve_static_assetszostała zmieniona na, config.serve_static_filesaby wyjaśnić jej rolę.

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

Ustaw więc env RAILS_SERVE_STATIC_FILESlub using Nginxdo obsługi plików statycznych. Dodawanie config.serve_static_assets = truebędzie nadal działać, ale zostanie usunięte w przyszłości.


1

nie jest zalecane, aby kapistrano dokonywał prekompilacji zasobów, ponieważ może to zająć całe wieki i często przerwać. spróbuj wykonać prekompilację zasobów lokalnych.

Najpierw ustaw w config / application.rb, config.assets.initialize_on_precompile = false a następnie wykonaj lokalne RAILS_ENV=production bin/rake assets:precompile i dodaj te public / asset do git.

i config / environment / development.rb, zmień ścieżkę do zasobów, aby uniknąć używania zasobów prekompilowanych:

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

Jeśli masz problem z połączeniem z bazą danych, oznacza to, że masz inicjator korzystający z bazy danych. sposobem obejścia tego problemu jest ustawienie nowego środowiska przez zduplikowanie pliku production.rb jako być może production2 .rb, a następnie w database.yml dodanie środowiska production2 z ustawieniem bazy danych deweloperskich . to zrób

RAILS_ENV=production2 bin/rake assets:precompile

jeśli nadal masz problem z zasobami, na przykład ckeditor, dodaj plik js do config / initializers / asset.rb

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


0

Może się mylę, ale ci, którzy zalecają zmianę

config.assets.compile = true

Komentarz w tym wierszu brzmi: # Nie wracaj do potoku aktywów, jeśli brakuje wstępnie skompilowanego zasobu.

Sugeruje to, że ustawiając to na true, nie naprawiasz problemu, ale raczej omijasz go i uruchamiasz potok za każdym razem. To z pewnością musi zabić twoją wydajność i zniweczyć cel rurociągu?

Miałem ten sam błąd i był to skutek działania aplikacji w podfolderze, o którym railsy nie wiedziały.

Więc mój plik css jest w home / subfolder / app / public / .... ale railsy szukały w home / app / public / ...

spróbuj przenieść swoją aplikację z podfolderu lub powiedzieć railsom, że jest w podfolderze.


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

To rozwiązało problem w produkcji. Umieść go w konfiguracji nginx.


0

Nawet my stanęliśmy przed tym samym problemem, w którym RAILS_ENV=production bundle exec rake assets:precompileudało się, ale rzeczy nie działały zgodnie z oczekiwaniami.
Okazało się, że głównym winowajcą był jednorożec.

Tak jak w Twoim przypadku, nawet my ponownie uruchamialiśmy jednorożca po skompilowaniu zasobów. Zauważono, że po ponownym uruchomieniu jednorożca uruchamiane są tylko jego procesy robocze, a nie proces główny.
Jest to główny powód, dla którego nie są wyświetlane prawidłowe zasoby.

Później, po skompilowaniu zasobów, zatrzymaliśmy się i uruchomiliśmy unicorn, aby proces wzorca unicorn również został ponownie uruchomiony, a prawidłowe zasoby były obsługiwane.
Zatrzymanie i uruchomienie jednorożca przynosi około 10 sekund przestoju w porównaniu do ponownego uruchomienia jednorożca. Jest to obejście, które można zastosować, gdy rozwiązanie długoterminowe jest przenoszone do pumy z jednorożca.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.