Rails - application.css не найден в производственном режиме

Я обновляю приложение для использования конвейера активов.

У меня есть css-ресурсы, скомпилированные в файл css приложения, но они не найдены, когда я запускаю приложение в рабочем режиме с помощью

RAILS_ENV=production bundle exec rails s

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

ActionController::RoutingError (No route matches [GET] 
"/assets/default.scss-1a27c...f07c.css"):

Несмотря на то, что этот файл существует в public/assets

$ ls public/assets/def*
public/assets/default.scss-1a27c...f07c.css     public/assets/default.scss.css
public/assets/default.scss-1a27c...f07c.css.gz  public/assets/default.scss.css.gz

Что мне нужно изменить, чтобы заставить сервер найти файл актива?

То же самое происходит и для других .css файлов. Они компилируются в общедоступные/активы с отпечатками пальцев, но затем не найдены.

Источник страницы показывает:

<link href="/assets/default.scss-1a27c...f07c.css" 
media="screen" rel="stylesheet" type="text/css" />

Источником рельсов (haml) является = stylesheet_link_tag 'default.scss.css'

public.assets curently includes содержит следующие файлы.

$ ls public/assets/def*
public/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css
public/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css.gz
public/assets/default.scss.css
public/assets/default.scss.css.gz

application.rb имеет

$ cat config/application.rb 
require File.expand_path('../boot', __FILE__)

# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line
  # Bundler.require(:default, :assets, Rails.env)
end

module Linker
  class Application < Rails::Application
    config.encoding = "utf-8"
    config.filter_parameters += [:password]
    config.assets.enabled = true
    config.assets.initialize_on_precompile = false # For Heroku
    config.assets.version = '1.0'
  end
end

config/environments/production имеет:

$ cat config/environments/production.rb 
Linker::Application.configure do
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true
  config.assets.precompile += ['default.scss.css','main.css', 'jquery-ui-1.8.22.custom.css']
  config.serve_static_assets = false
  config.assets.compress = true
  config.assets.compile = false
  config.assets.digest = true
  config.log_level = :debug
  config.i18n.fallbacks = true
  config.active_support.deprecation = :notify
end

Кажется, что это происходит для всех активов, например.

Started GET "/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/default.scss-1a27c22229b7b522066181f27af4f07c.css"):
Started GET "/assets/main-6864687b4114a1c316e444bd90f233ff.css" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/main-6864687b4114a1c316e444bd90f233ff.css"):
Started GET "/assets/jquery-ui-1.8.22.custom-24319b4b1218846a3fe22a0479ae98b4.css" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/jquery-ui-1.8.22.custom-24319b4b1218846a3fe22a0479ae98b4.css"):
Started GET "/assets/application-fc1d492d730f2a45581a40eac4607db8.js" for 127.0.0.1 at 2014-02-23 10:24:47 -0500
ActionController::RoutingError (No route matches [GET] "/assets/application-fc1d492d730f2a45581a40eac4607db8.js"):
Started GET "/images/link.ico" for 127.0.0.1 at 2014-02-23 10:24:48 -0500
ActionController::RoutingError (No route matches [GET] "/images/link.ico"):

Ответ 1

Rails по умолчанию не обслуживает активы под public. Смотрите ваш production.rb:

  config.serve_static_assets = true

Измени это на истину, и все готово. (Примечание: вы не хотите, чтобы это было true в производстве, не забудьте поменять его обратно перед развертыванием!)

Подробности смотрите в Настройка Rails-приложений.

В рельсах 6, по умолчанию production.rb должна быть строка

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

Итак, запустите свой сервер с помощью

RAILS_SERVE_STATIC_FILES=true rails server -e production

или установите config.public_file_server.enabled=true в production.rb. Смотрите ответы ниже для рельсов 4 и 5.

Ответ 2

Решение Rails 5 похоже на решение Rails 4, данное Жюлем Коуплендом выше.

В вашем предварительно сгенерированном файле config/environments/production.rb должна быть запись, которая выглядит примерно так:

# Disable serving static files from the '/public' folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

Я нашел достойное объяснение этого параметра в Руководстве по настройке Rails Applications на http://guides.rubyonrails.org:

config.public_file_server.enabled настраивает Rails для обслуживания статического файлы из публичного каталога. Эта опция по умолчанию имеет значение true, но в производственная среда имеет значение false, потому что сервер программное обеспечение (например, NGINX или Apache), используемое для запуска приложения, должно служить вместо статических файлов. Если вы работаете или тестируете свое приложение в производственный режим с использованием WEBrick (не рекомендуется использовать WEBrick в производство) установите для параметра значение true. В противном случае вы не сможете использовать кэширование страниц и запрашивать файлы, которые существуют в общедоступных Каталог.

Заключение: В производственном процессе запуск вашего сервера rails с RAILS_SERVE_STATIC_FILES=1 позволит Rails обслуживать любые файлы в каталоге public/assets так же, как это делал бы веб-сервер. Имейте в виду, что Rails является сервером приложений и не будет делать это так же эффективно, как веб-сервер (например, NGINX, Apache и т.д.). Для реальных приложений у вас должен быть выделенный веб-сервер, стоящий перед Rails, который будет обслуживать статические ресурсы сам по себе и при необходимости использовать только Rails для динамического контента. Подробнее читайте в этой статье Джастина Вейса о различиях между веб-серверами и серверами приложений.

Ответ 3

В Rails 4 вы можете заставить их отображаться в процессе производства (выполняется локально), передавая переменную окружения:

RAILS_SERVE_STATIC_FILES=true rails server -e production

Это должно работать до тех пор, пока у вас есть эта строка в /config/environments/production.rb:

config.serve_static_files = ENV ['RAILS_SERVE_STATIC_FILES']. present?

Ответ 4

Когда вы выполняете rake assets:precompile, ваши активы переходят в общий каталог. Посмотрите, можете ли вы найти эти файлы в public/assets/

Вы должны увидеть что-то вроде этого:

I, [2014-02-23T20:06:21.853314 #26915]  INFO -- : Writing app_root/public/assets/application-ecd8636fc80ea2b712039c4abc365da9.css