Рейки 4: активи, які не завантажуються у виробництво


116

Я намагаюся вкласти своє додаток у виробництво, а зображення та шляхи активів css не працюють.

Ось що я зараз роблю:

  • Графічні активи живуть у /app/assets/images/image.jpg
  • Таблиці стилів живуть у /app/assets/stylesheets/style.css
  • У своєму макеті я посилаю на файл css так: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
  • Перш ніж перезапустити єдиноріг, я запускаю, RAILS_ENV=production bundle exec rake assets:precompileі це вдається, і я бачу файли з відбитками пальців у public/assetsкаталозі.

Коли я переглядаю свій сайт, я отримую помилку 404 не знайдено mysite.com/stylesheets/styles.css.

Що я роблю неправильно?

Оновлення: У моєму макеті це виглядає приблизно так:

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

Генератор джерела такий:

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

Схоже, Rails неправильно шукає зібрані файли css. Але це дуже заплутано, чому він працює правильно для javascripts (помічайте /assets/****.jsшлях).


Чи можете ви сказати нам, як ви завантажуєте свій файл css? З вашої помилки виходить, що ви намагаєтеся поправити її, а не використовувати stylesheet_link_tag.
kik

1
Щойно додано вище. Я роблю<%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" => true %>
emersonthis

Гаразд, тому я б рекомендував дві речі: 1. перевірити створене джерело, чи цей рядок записано як шлях до public/assetsта 2. подвійну перевірку, якщо десь не існує іншої інструкції, яка намагається завантажити цей файл css (імовірно, жорстко закодований)
kik

Я не можу сказати, чи використання проблеми .erb є проблемою, оскільки я ніколи цього не роблю: .home {background: #FFF url(<%= image_path 'hippopotamus.jpg' %>) no-repeat; }насправді можна замінити на зірочку на .home {background: #FFF url(image-path('hippopotamus.jpg')) no-repeat; }. Можливо, ви можете спробувати, якщо це допоможе.
kik

Ви говорите, що я можу зробити це посилання у файлі css динамічним, не додаючи розширення .erb? Я змінив її, бо не хотів, щоб посилання розірвалася, коли я перебуваю в режимі розробки.
emersonthis

Відповіді:


105

У рейках 4 вам потрібно внести зміни нижче:

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

Це працює зі мною. використовувати наступну команду для попереднього компілювання активів

RAILS_ENV=production bundle exec rake assets:precompile

Удачі!


11
Я думав, що налаштування config.assets.compile в істину знищить продуктивність у виробництві. також, css.erb? хто цим користується? а що з sass і кавою?
ahnbizcad

коли запитуються файли кави та sass, вони обробляються процесорами, наданими кофе-скриптом та дорогоцінними каменями sass-rails, а потім надсилаються назад у браузер як JavaScript та CSS відповідно.
Rameshwar Vyevhare

1
Цю проблему вже вирішено для Rails 4, тому немає необхідності використовувати дорогоцінний камінь turbo-lanque-rails3
Рамешвар Виєваре

4
Вибачте, я не в змозі зв’язати те, що ви сказали, щоб відповісти на моє запитання.
ahnbizcad

1
Зазвичай під час запуску виробничого сервера ви будете запускати Rails із пасажирським або єдинорогом або puma за веб-сервером Apache або nginx. Краще дозволити Apache або nginx обслуговувати статичні файли (js, css, зображення), а сервер додатків Rails (puma, єдиноріг) обслуговувати код і шаблон Rails. Для цього вам слід вимкнути config.serve_static_filesта налаштувати псевдоніми в Apache та nginx для вирішення assets.
Châu Hồng Lĩnh

85

У мене була та сама проблема, і я знайшов цей параметр у config / environment / production.rb:

# Rails 4:
config.serve_static_assets = false

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

Змінивши його на true він працював. Схоже, за замовчуванням Rails очікує, що ви налаштували свій зовнішній веб-сервер для обробки запитів для файлів із загальнодоступної папки замість того, щоб наближати їх до програми Rails. Можливо, ви зробили це для своїх файлів javascript, але не для ваших таблиць стилів CSS?

( Див. Документацію Rails 5 ). Як зазначається в коментарях, за допомогою Rails 5 ви можете просто встановити RAILS_SERVE_STATIC_FILESзмінну середовища, оскільки налаштування за замовчуванням є config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?.


1
ПОПЕРЕДЖЕННЯ ПОПЕРЕДЖЕННЯ: Параметр конфігурації config.serve_static_assetsбуло перейменовано на config.serve_static_filesуточнення його ролі (воно лише дозволяє обслуговувати все в publicпапці і не пов'язане з конвеєром активів). serve_static_assetsІм'я користувача треба увійти на сайт Rails 5.0. Будь ласка, перенесіть свої конфігураційні файли відповідно.
yekta

Раніше, коли я стикався з цією проблемою, змінивши цю лінію, вона вирішила її для мене, але зараз я знову зіткнулася з нею (не знаю, як я продовжую закінчуватися в цих ситуаціях.), І цього недостатньо. Будь-які пропозиції щодо того, що може бути не так?
IIllII

2
Це має бути прийнятою відповіддю. Хоча це і config.serve_static_filesв Rails 4.2, і config.public_file_server.enabledв Rails 5 . @see github.com/heroku/rails_serve_static_assets/blob/master/lib/…
Лукас Нельсон

3
Rails 5.0.0.1 config / environment / production.rb містить, config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?щоб ви могли встановити це по-різному для свого середовища, не змінюючи код, який зареєстрований у вашій SCM.
tobinjim

Щоб увімкнути це: "export RAILS_SERVE_STATIC_FILES =" тоді ви запустите "rails s -e production" Щоб відключити його: "unset RAILS_SERVE_STATIC_FILES"
Альфредо

32

У /config/environments/production.rbмені довелося додати це:

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

.Js вже отримували попередню компіляцію, але я все одно додав її. Очевидно, що .css та .css.erb не відбуваються автоматично. В ^[^_]виключає обертони з компілюються - це регулярний вираз.

Трохи засмучує те, що документи чітко заявляють, що конвеєр активів IS включений за замовчуванням, але не пояснює той факт, який стосується лише javascripts.


Вам потрібно додати styles.css для config.assets.precompile
Frederick Cheung

23

Я був в змозі вирішити цю проблему за рахунок зміни: config.assets.compile = falseдо
config.assets.compile = trueін/config/environments/production.rb

Оновлення (24 червня 2018 р.) : Цей метод створює вразливість безпеки, якщо версія Sprockets, яку ви використовуєте, менша за 2.12.5, 3.7.2 або 4.0.0.beta8


7
Чи це не означає, що Rails збирає активи замість, скажімо, завантаження з CDN?
Бенджамін Оукс

@BenjaminOakes Так, і саме цього я хотів
Янофський

2
Цей режим використовує більше пам’яті, працює менше, ніж за замовчуванням, і не рекомендується. Краще використовувати проксі-сервер nginx.
yekta

16

Для Rails 5 слід включити наступний конфігураційний код:

config.public_file_server.enabled = true

За замовчуванням Rails 5 постачається з такою лінією конфігурації:

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

Отже, вам потрібно буде встановити змінну середовища RAILS_SERVE_STATIC_FILESна істинне.


1
Для Rails 5 я повинен додати, я встановив passenger_env_var RAILS_SERVE_STATIC_FILES true;у блоці розташування свого додатка у своєму файлі nginx.conf.
Мартін Велес

10

Щоб обслуговувати активи у виробництві, ви повинні виконати дві речі:

  1. Попередньо складіть активи.
  2. Обслуговуйте активи на сервері для браузера.

1) Для попереднього компілювання активів у вас є кілька варіантів.

  • Ви можете запустити rake assets:precompileна своїй локальній машині, зобов'язати її керувати вихідним кодом (git), а потім запустити програму розгортання, наприклад capistrano. Це не гарний спосіб привласнення попередньо складених активів до SCM.

  • RAILS_ENV=production rake assets:precompileПеред тим, як перезапустити сервер, ви можете написати завдання граблі, яке виконується на цільових серверах щоразу, коли ви розгортаєте додаток Rails до виробництва.

Код у завданні для capistrano буде виглядати приблизно так:

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) Тепер у вас є активи на виробничих серверах, вам потрібно обслуговувати їх для браузера.

Знову ж таки, у вас є кілька варіантів.

  • Увімкніть статичний файл Rails, який обслуговується в config / середовища / production.rb

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

    Використання Rails для подання статичних файлів призведе до знищення продуктивності програми Rails.

  • Налаштуйте nginx (або Apache) для обслуговування статичних файлів.

    Наприклад, мій nginx, який був налаштований на роботу з Puma, виглядає так:

    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 більше не генерує відпечатану версію об’єкта: stylesheets / style.css не буде створено для вас.

Якщо ви використовуєте, stylesheet_link_tagто буде створено правильне посилання на вашу таблицю стилів

Крім того, styles.cssмає бути config.assets.precompileсписок речей, які попередньо складені


Я бачу файл відбитків пальців у каталозі / public / tools /. У моєму макеті я маю таке: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>це неправильно? `
emersonthis

Чомусь виробниче розгортання все ще вказує на оригінальні файли, коли я переглядаю джерело. <link data-turbolinks-track="true" href="https://stackoverflow.com/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />Але файли javascript правильні! Я не розумію, чому однакові конфігурації працюють для файлів .js, але не .css.
emersonthis

На Rails 5.0.0.beta3 я отримую це попередження: ЗАСТЕРЕЖЕННЯ ПОПЕРЕДЖЕННЯ: serve_static_filesзастаріле і буде видалено в Rails 5.1. Будь ласка, використовуйте public_file_server.enabled = trueзамість цього.
GMA

@emersonthце Те саме! Js завантажується ідеально, але деякі файли css отримують 404. Ви вирішили це?
IvRRimUm

Це майже ВЖЕ є проблема з конфігурацією конвеєра майна. Якщо у вас є файли в будь-якому місці, яке не за замовчуванням, це майже напевно проблема, і вам потрібно повідомити про це конвеєр активів, використовуючи щось на зразок першої відповіді.
emersonthis

3

змінити рядок файлів Production.rb

config.assets.compile = false

в

config.assets.compile = true

а також додати

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

навіщо компілювати? ми не будемо припускати збирати на виробництві під час його запуску
Джеймс Тан

1
НІКОЛИ не робіть цього! Будь-яке налаштування config.assets.compile для справжнього у виробництві має бути знято.
bkunzi01

2

Я запускаю Ubuntu Server 14.04 , Ruby 2.2.1 та Rails 4.2.4. Я дотримувався програми Turorial розгортання від DigitalOcean і все пішло добре, але коли я до браузера і ввожу IP-адресу мого VPS, додаток завантажується, але без стилі та JavaScript.

Додаток працює з Unicorn та Nginx . Щоб вирішити цю проблему, я ввійшов на свій сервер за допомогою SSH з моїм користувачем "розгортачем" і переходжу до мого шляху додатка, який є "/ домашній / розгортальник / програми / блог" і виконую наступну команду:

RAILS_ENV=production bin/rake assets:precompile

Тоді я просто перезавантажую VPS і це все! Це працює для мене!

Сподіваюся, це може бути корисним для когось іншого!


2

Якщо встановлено попередній компіляцію, НЕ потрібно

config.assets.compile = true

тому що це служіння активам наживо.

Нашою проблемою було те, що у нас була створена база секретних ключів розробки config/secrets.yml

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Потрібен запис для виробничого середовища


1
як згадується в інших відповідях, які вам потрібні config.assets.precompile = ['*.js', '*.css', '*.css.erb'] та запускатиRAILS_ENV=production bundle exec rake assets:precompile
xxjjnn

1
це дає змогу збирати активи під час роботи на виробництві, дуже повільно, не так
Джеймс Тан

2

ЧОГО НЕ БУДЕ НЕ робити:

Деякі мої колеги вище рекомендували вам це зробити:

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

Трубопровід активів рейки говорить про вищезазначений підхід:

Цей режим використовує більше пам’яті, працює менше, ніж за замовчуванням, і не рекомендується. Дивіться тут: ( http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation )

ЧОГО ТИ ПОВИНЕН:

Попередньо складіть свої активи.

RAILS_ENV=production rake assets:precompile

Можливо, ви можете це зробити за допомогою граблі.


Навіщо додавати артефакти збірки до git? Ви можете просто додати завдання граблі у свій процес збирання та уникати масового gitspam (особливо якщо у вас є більш утилізатор та gzipping, що вам слід)
Dr.Strangelove

@ Dr.Strangelove Дякую за ваш коментар - я про це недостатньо знаю -: чи можете ви розробити / відредагувати оригінальну публікацію?
BKSpurgeon

1

Матч за замовчуванням для компіляції файлів включає application.js, application.css та всі не-JS / CSS файли (сюди автоматично включатимуться всі активи зображень) з папок додатків / активів, включаючи ваші дорогоцінні камені:

Якщо у вас є інші маніфести чи окремі таблиці стилів та файли JavaScript, ви можете додати їх до масиву попередньої компіляції в config / inicijalizers / elements.rb:

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

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


1

Перш за все, перевірте свої активи, можливо, є якась помилка при попередньому складанні активів.

Для попереднього складання активів у виробництві ENV виконайте цю команду:

RAILS_ENV=production rake assets:precompile

Якщо вона показує помилку, видаліть її спочатку,

У разі помилки "невизначеної змінної" завантажте цей файл змінної, перш ніж використовувати його в іншому файлі.

приклад:

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

у файлі application.rb встановлюється послідовність попередньої компіляції активів

приклад:

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

Знайшов це:

Параметр конфігурації config.serve_static_assetsперейменовано наconfig.serve_static_files щоб уточнити його роль.

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

Тому встановіть env RAILS_SERVE_STATIC_FILESабо використовуйте Nginxдля обслуговування статичних файлів. Додати config.serve_static_assets = trueвсе одно буде працювати, але видалено в майбутньому.


1

не рекомендується дозволяти Capistrano робити активи до попереднього компіляції, оскільки це може зайняти віки і часто вичерпати час. спробуйте зробити місцеві активи докомпіляції.

По-перше, встановіть у config / application.rb, config.assets.initialize_on_precompile = false а потім зробіть локальний RAILS_ENV=production bin/rake assets:precompile і додайте ці відкриті / активи до git.

і config / environment / development.rb, змініть шлях до активів, щоб уникнути використання попередньо складених активів:

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

Якщо у вас є проблема з підключенням db, значить, у вас є ініціалізатор, який використовує db. Один із способів навколо цього - встановити нове середовище шляхом дублювання production.rb, як, можливо, production2 .rb, а в database.yml додати середовище production2 з налаштуваннями db розвитку . то зробіть

RAILS_ENV=production2 bin/rake assets:precompile

якщо ви все ще стикаєтеся з якоюсь проблемою з активами, наприклад ckeditor, додайте файл js в config / inicijalizer / elements.rb

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


0

Я можу помилятися, але ті, хто рекомендує змінити

config.assets.compile = true

У коментарі до цього рядка написано: # Не відступайте до конвеєра активів, якщо попередньо складений актив пропущено.

Це говорить про те, що встановивши це значення true, ви не виправляєте проблему, а обминаєте її та запускаєте конвеєр щоразу. Це, безумовно, повинно вбити вашу продуктивність і перемогти мету трубопроводу?

У мене була така сама помилка, і це було пов’язано з тим, що програма працювала в підпапці, про яку рейки не знали.

Тож мій файл css, де в домашній / підпапці / додатку / публічному / .... але рейки шукав у домашньому / додатку / публічному / ...

спробуйте або перемістити додаток із підпапки, або скажіть, що воно знаходиться в підпапці.


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

Це вирішило проблему для мене у виробництві. Помістіть його в nginx config.


0

Навіть ми стикалися з тією ж проблемою, де це RAILS_ENV=production bundle exec rake assets:precompileвдалося, але все не вийшло так, як очікувалося.
Ми виявили, що єдиноріг тут був головним винуватцем.

Як у вашому випадку, навіть ми звикли перезапустити єдиноріг після складання активів. Помічено, що при перезапуску єдинорога перезапускаються лише його робітничі процеси, а не головний.
Це головна причина, коли правильні активи не подаються.

Пізніше, після складання активів, ми зупинилися і почали єдиноріг, так що процес відновлення єдиноріг також був запущений і правильні активи стали обслуговуватися.
Зупинка та запуск єдинорога приносить близько 10 секунд простою в порівнянні з перезапуском єдинорога. Це рішення, яке може бути використане там, коли довготривале рішення переходить до пуми від єдинорога.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.