it-roy-ru.com

Rails 4: активы не загружаются в производство

Я пытаюсь поместить свое приложение в производство, а пути ресурсов изображений и CSS не работают.

Вот что я сейчас делаю:

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

Когда я просматриваю свой сайт, я получаю ошибку 404 not found для 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).

113
emersonthis

В /config/environments/production.rb я должен был добавить это:

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

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

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

32
emersonthis

В Rails 4 вам нужно внести следующие изменения:

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

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

Rails_ENV=production bundle exec rake assets:precompile

Удачи!

100
Rameshwar Vyevhare

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

76
davmac

Я смог решить эту проблему, изменив: config.assets.compile = false на
config.assets.compile = true in /config/environments/production.rb

Update (24 июня 2018 г.): этот метод создает уязвимость системы безопасности , если используемая вами версия Sprockets меньше 2.12.5, 3.7.2 или 4.0.0.beta8

22
Yanofsky

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

10
ytbryan

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

  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/средах/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;
    }
    
9
Châu Hồng Lĩnh

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

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

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

4
Frederick Cheung

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

config.assets.compile = false

в 

config.assets.compile = true

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

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

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

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

Rails_ENV=production bin/rake assets:precompile

Тогда я просто перезагружаю VPS и все! У меня работает!

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

2
Alex Ventura

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

config.assets.compile = true

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

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

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Нужен вход для производственной среды

2
xxjjnn

То, что вы не должны делать:

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

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

В конвейере активов Rails говорится о вышеуказанном подходе: 

Этот режим использует больше памяти, работает хуже, чем по умолчанию, и не рекомендуется. Смотрите здесь: ( http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation )

Что ты должен делать:

1. Прекомпилируйте ваши ресурсы.

Rails_ENV=production rake assets:precompile

2. Добавьте эти файлы в git.

git add –-all

3. Перенесите изменения в основную ветку и заново разверните.

git Push Origin master

2
BKSpurgeon

Нашел это:

Параметр конфигурации 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
Daniel Wei

Сопоставление по умолчанию для компиляции файлов включает 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

1
FreePender

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

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

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

0
Bhavya Keniya

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

Во-первых, установите в 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'

Если у вас проблема с БД, значит у вас есть инициализатор, который использует БД. Одним из способов решения этой проблемы является установка новой среды с помощью дубликата production.rb, например, production2 . rb, а в файле database.yml добавьте production2 environment с параметром development db. тогда делай

Rails_ENV=production2 bin/rake assets:precompile

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

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

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

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

0
Pedro Adame Vergara

Я могу ошибаться, но те, кто рекомендует изменить

config.assets.compile = true

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

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

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

Так что мой файл CSS находится в home/subfolder/app/public/.... но Rails искал в home/app/public/...

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

0
Brad

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

Для предварительной компиляции ресурсов в производственном 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']
0
Chitresh goyal