Rails 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путь).

emersonthis
источник
Можете ли вы рассказать нам, как вы загружаете свой файл 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 в true убьет производительность в продакшене. также css.erb? кто этим пользуется? а как насчет нахальства и кофе?
ahnbizcad
когда запрашиваются файлы coffee и sass, они обрабатываются процессорами, предоставляемыми гемами coffee-script и sass-rails, а затем отправляются обратно в браузер как JavaScript и CSS соответственно.
Rameshwar Vyevhare 01
1
Эта проблема уже решена для Rails 4, поэтому нет необходимости использовать драгоценный камень turbo-sprocket-rails3
Рамешвар Виеваре 01
4
Извините, я не могу связать то, что вы сказали, чтобы ответить на мой вопрос.
ahnbizcad 01
1
Обычно, когда вы запускаете производственный сервер, вы запускаете Rails с пассажиром, единорогом или puma за веб-сервером Apache или nginx. Лучше позволить Apache или nginx обслуживать статические файлы (js, css, изображения), а сервер приложений Rails (puma, unicorn) обслуживать код и шаблон 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?.

davmac
источник
1
ПРЕДУПРЕЖДЕНИЕ ОБ УСТАРЕНИИ. Параметр конфигурации config.serve_static_assetsбыл переименован в, config.serve_static_filesчтобы уточнить его роль (он просто позволяет обслуживать все в publicпапке и не имеет отношения к конвейеру ресурсов). serve_static_assetsПсевдоним будет удален в Rails 5.0. Пожалуйста, перенесите ваши файлы конфигурации соответствующим образом.
yekta
Раньше, когда я сталкивался с этой проблемой, изменение этой строки решило ее для меня, но теперь я снова сталкиваюсь с ней (я не знаю, как я продолжаю попадать в такие ситуации), и этого недостаточно. Есть еще предложения относительно того, что может быть не так?
IIllIIll
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 не происходят автоматически. В ^[^_]исключает обертоны из компилируются - это регулярное выражение.

Немного расстраивает то, что в документации четко указано, что конвейер ресурсов включен по умолчанию, но не разъясняется тот факт, что это относится только к javascripts.

emersonthis
источник
Вам нужно добавить styles.css в config.assets.precompile
Фредерик Чунг
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

Yanofsky
источник
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значение true.

ytbryan
источник
1
Для Rails 5, я должен добавить, я установил passenger_env_var RAILS_SERVE_STATIC_FILES true;блок местоположения моего приложения в моем файле nginx.conf.
Мартин Велес,
10

Чтобы задействовать ресурсы в производстве, необходимо выполнить 2 вещи:

  1. Предварительно скомпилируйте активы.
  2. Подавайте ресурсы на сервере в браузер.

1) Для предварительной компиляции ресурсов у вас есть несколько вариантов.

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

  • Вы можете написать задачу rake, которая будет запускаться 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 / environment / 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 больше не генерирует версию ресурса без отпечатков пальцев: таблицы стилей / style.css не будут созданы для вас.

Если вы используете, stylesheet_link_tagто будет сгенерирована правильная ссылка на вашу таблицу стилей.

Кроме того, styles.cssдолжен быть config.assets.precompileсписок вещей, которые предварительно скомпилированы

Фредерик Чунг
источник
Я вижу файл с отпечатками пальцев в каталоге / public / assets /. В моем макете у меня есть следующее: <%= 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
@emersonthis То же самое! 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 значение true в рабочей среде, должен быть застрелен.
bkunzi01
2

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

Приложение работает с Unicorn и Nginx . Чтобы решить эту проблему, я вошел на свой сервер с помощью SSH с моим пользовательским «развертывателем» и перешел по пути к моему приложению «/ home / deployer / apps / blog» и запустил следующую команду:

RAILS_ENV=production bin/rake assets:precompile

Затем я просто перезапускаю VPS и все! Меня устраивает!

Надеюсь, это может быть полезно для кого-то еще!

alexventuraio
источник
2

Если установлена ​​предварительная компиляция, вам НЕ нужно

config.assets.compile = true

поскольку это для обслуживания активов вживую.

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

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Требуется вход в производственную среду

xxjjnn
источник
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

Вероятно, вы сможете сделать это с помощью задачи с граблями.

BKSpurgeon
источник
Зачем же добавлять артефакты сборки в git? Вы можете просто добавить задачу рейка в свой процесс сборки и избежать массового gitspam (особенно если у вас есть uglifier и gzip, что вам и нужно),
доктор Стрейнджлав
@ Dr.Strangelove Спасибо за ваш комментарий - я не знаю об этом достаточно -: вы можете уточнить / отредактировать исходный пост?
BKSpurgeon
1

Сопоставитель по умолчанию для компиляции файлов включает application.js, application.css и все файлы, отличные от JS / CSS (это автоматически будет включать все ресурсы изображений) из папок app / assets, включая ваши драгоценные камни:

Если у вас есть другие манифесты или отдельные таблицы стилей и файлы JavaScript для включения, вы можете добавить их в массив прекомпиляции в config / initializers / assets.rb:

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

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

FreePender
источник
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или using Nginxдля обслуживания статических файлов. Добавление config.serve_static_assets = trueбудет по-прежнему работать, но будет удалено в будущем.

Даниэль Вэй
источник
1

не рекомендуется позволять capistrano выполнять предварительную компиляцию ресурсов, потому что это может занять много времени и часто превышает время ожидания. попробуйте выполнить предварительную компиляцию локальных ресурсов.

1-й, установите в config / application.rb, config.assets.initialize_on_precompile = false затем выполните local RAILS_ENV=production bin/rake assets:precompile и добавьте эти общедоступные / активы в git.

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

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

Если у вас проблема с подключением к базе данных, это означает, что у вас есть инициализатор, который использует базу данных. один из способов - установить новую среду, дублируя production.rb как, возможно, production2 .rb, а в database.yml добавить production2 среду с настройкой разработки . тогда делай

RAILS_ENV=production2 bin/rake assets:precompile

если вы все еще сталкиваетесь с некоторыми проблемами с активами, например ckeditor, добавьте файл js в config / initializers / assets.rb

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

Джеймс Тан
источник
0

Возможно я ошибаюсь но тем кто рекомендует менять

config.assets.compile = true

Комментарий к этой строке гласит: # Не возвращаться к конвейеру ресурсов, если предварительно скомпилированный актив пропущен.

Это говорит о том, что, задав для него значение true, вы не устраняете проблему, а, скорее, обойдете ее и каждый раз запускаете конвейер. Это обязательно должно убить вашу производительность и уничтожить цель конвейера?

У меня была такая же ошибка, и это было из-за того, что приложение работало в подпапке, о которой рельсы не знали.

Итак, мой файл css находится в home / subfolder / app / public / .... но rails искал в home / app / public / ...

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

штифтик
источник
0
location ~ ^/assets/ {
  expires 1y;
  add_header Cache-Control public;
  add_header ETag "";
}

Это устранило у меня проблему в продакшене. Поместите его в конфиг nginx.

Педро Адаме Вергара
источник
0

Даже мы столкнулись с той же проблемой, когда это RAILS_ENV=production bundle exec rake assets:precompileудалось, но все пошло не так, как ожидалось.
Мы обнаружили, что главным виновником здесь был единорог.

То же, что и в вашем случае, даже мы использовали для перезапуска единорога после компиляции ресурсов. Было замечено, что при перезапуске единорога перезапускаются только его рабочие процессы, а не главный процесс.
Это основная причина, по которой не обслуживаются нужные активы.

Позже, после компиляции ассетов, мы остановили и запустили единорога, так что мастер-процесс единорога также перезапустился и были обслужены правильные ассеты.
Остановка и запуск единорога дает около 10 секунд простоя по сравнению с перезапуском единорога. Это обходной путь, который можно использовать, когда долгосрочным решением является переход на puma от unicorn.

Бхавья Кения
источник