Рельсы 4: активы, не загружаемые в производство

Я пытаюсь поместить свое приложение в производство, а пути образа и 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.

Что я делаю неправильно?

Update: В моем макете это выглядит так:

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

Ответ 1

В /config/environments/production.rb мне пришлось добавить это:

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

.js уже предварительно скомпилировался, но я все равно добавил. Скобки .css и .css.erb, по-видимому, не происходят автоматически. ^[^_] исключает частичные компиляции - это регулярное выражение.

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

Ответ 2

В рельсах 4 вам необходимо внести следующие изменения:

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

Это работает со мной. используйте следующую команду для предварительной компиляции активов

RAILS_ENV=production bundle exec rake assets:precompile

Удачи!

Ответ 3

У меня была такая же проблема, и я нашел этот параметр в config/средах/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?.

Ответ 4

Я смог решить эту проблему, изменив: 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.

Ответ 5

Для 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.

Ответ 6

Есть две вещи, которые вы должны выполнить, чтобы обслуживать активы в производстве:

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

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

Ответ 7

Rails 4 больше не генерирует несертифицированную версию актива: stylesheets/style.css не будут созданы для вас.

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

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

Ответ 8

измените строку файла Production.rb

config.assets.compile = false

в

config.assets.compile = true

а также добавьте

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

Ответ 9

То, что вы НЕ ДОЛЖНЫ делать:

Некоторые из моих коллег выше рекомендовали вам сделать это:

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

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

Ответ 10

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

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

RAILS_ENV=production bin/rake assets:precompile

Затем я просто перезапускаю VPS и это! Это работает для меня!

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

Ответ 11

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

config.assets.compile = true

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

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

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Необходимая запись для производственной среды

Ответ 12

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

Если у вас есть другие манифесты или отдельные таблицы стилей и файлы 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

Ответ 13

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

Для предварительной компиляции активов в производстве ENV выполните следующую команду:

RAILS_ENV=production rake assets:precompile

Если он показывает ошибку, сначала удалите это,

В случае ошибки undefined variable "загрузите этот файл переменной перед тем, как использовать его в другом файле.

Пример:

@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']

Ответ 14

Найдено следующее:

Вариант конфигурации 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 будет по-прежнему работать, но удаляется в будущем.

Ответ 15

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

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

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

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

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

RAILS_ENV=production2 bin/rake assets:precompile

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

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

Ответ 16

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

config.assets.compile = true

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

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

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

Итак, мой файл css, где в home/subfolder/app/public/...., но rails смотрел в home/app/public/...

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

Ответ 17

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

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

Ответ 18

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

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

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