Rails 4: activos que no se cargan en producción

116

Estoy tratando de poner mi aplicación en producción y las rutas de activos de imagen y CSS no funcionan.

Esto es lo que estoy haciendo actualmente:

  • Los activos de imagen se encuentran en /app/assets/images/image.jpg
  • Las hojas de estilo se encuentran en /app/assets/stylesheets/style.css
  • En mi diseño, hago referencia al archivo css de esta manera: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
  • Antes de reiniciar unicorn, ejecuto RAILS_ENV=production bundle exec rake assets:precompiley funciona correctamente y veo los archivos con huellas digitales en el public/assetsdirectorio.

Cuando navego a mi sitio, obtengo un error 404 no encontrado para mysite.com/stylesheets/styles.css.

¿Qué estoy haciendo mal?

Actualización: en mi diseño, se ve así:

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

La fuente de generación es esta:

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

Parece que Rails no está buscando correctamente los archivos CSS compilados. Pero es muy confuso por qué funciona correctamente para los javascripts (observe la /assets/****.jsruta).

emersonthis
fuente
¿Puede decirnos cómo carga su archivo css? Parece por su error que intenta vincularlo en lugar de usar stylesheet_link_tag.
kik
1
Recién agregado arriba. Estoy haciendo<%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" => true %>
emersonthis
Ok, entonces recomendaría dos cosas: 1. verificar la fuente generada si esta línea está escrita como ruta public/assetsy 2. verificar si no hay otra instrucción en algún lugar tratando de cargar ese archivo css (presumiblemente codificado)
kik
No puedo decir si usar .erb es un problema porque nunca lo hago: en .home {background: #FFF url(<%= image_path 'hippopotamus.jpg' %>) no-repeat; }realidad se puede reemplazar en sprocket con .home {background: #FFF url(image-path('hippopotamus.jpg')) no-repeat; }. Quizás puedas intentarlo si esto te ayuda.
kik
¿Estás diciendo que puedo hacer esa referencia en mi archivo css dinámico sin agregar la extensión .erb? Lo cambié porque no quería que el enlace se rompiera cuando estoy en modo de desarrollo.
emersonthis

Respuestas:

105

En rails 4, debe realizar los cambios a continuación:

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

Esto funciona conmigo. use el siguiente comando para precompilar activos

RAILS_ENV=production bundle exec rake assets:precompile

¡La mejor de las suertes!

Rameshwar Vyevhare
fuente
11
Pensé que configurar config.assets.compile en true matará el rendimiento en producción. también, css.erb? quien usa eso? y ¿qué pasa con el descaro y el café?
ahnbizcad
cuando se solicitan archivos de café y sass, los procesadores proporcionados por las gemas coffee-script y sass-rails los procesan y luego se envían al navegador como JavaScript y CSS respectivamente.
Rameshwar Vyevhare
1
Este problema ya se resolvió para Rails 4, por lo que no es necesario usar la gema turbo-sprocket-rails3
Rameshwar Vyevhare
4
Lo siento, no puedo establecer la conexión de lo que dijiste para responder a mi pregunta.
ahnbizcad
1
Normalmente, cuando ejecuta el servidor de producción, ejecutará Rails con el pasajero o unicornio o puma detrás del servidor web Apache o nginx. Es mejor dejar que Apache o nginx sirvan archivos estáticos (js, css, imágenes), y el servidor de aplicaciones Rails (puma, unicornio) sirva el código y la plantilla de Rails. Para hacerlo, debe apagar config.serve_static_filesy configurar el alias en Apache y nginx para tratar assets.
Châu Hồng Lĩnh
85

Acabo de tener el mismo problema y encontré esta configuración en config / environment / production.rb:

# Rails 4:
config.serve_static_assets = false

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

Cambiándolo para trueque funcione. Parece que, de forma predeterminada, Rails espera que haya configurado su servidor web front-end para manejar solicitudes de archivos fuera de la carpeta pública en lugar de enviarlos a la aplicación Rails. ¿Quizás ha hecho esto para sus archivos javascript pero no para sus hojas de estilo CSS?

( Consulte la documentación de Rails 5 ). Como se señaló en los comentarios, con Rails 5 puede configurar la RAILS_SERVE_STATIC_FILESvariable de entorno, ya que la configuración predeterminada es config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?.

davmac
fuente
1
ADVERTENCIA DE DEPRECATION: La opción de configuración config.serve_static_assetsha sido renombrada para config.serve_static_filesaclarar su función (simplemente habilita el servicio de todo en la publiccarpeta y no está relacionada con la canalización de activos). El serve_static_assetsalias se eliminará en Rails 5.0. Migre sus archivos de configuración en consecuencia.
yekta
Antes, cuando estaba enfrentando este problema, cambiar esa línea lo había resuelto para mí, pero ahora lo estoy enfrentando nuevamente (no sé cómo sigo terminando en estas situaciones) y esto no es suficiente. ¿Alguna sugerencia más sobre lo que podría estar mal?
IIllIIll
2
Esta debería ser la respuesta aceptada. Aunque está config.serve_static_filesen Rails 4.2 y config.public_file_server.enableden Rails 5 . @see github.com/heroku/rails_serve_static_assets/blob/master/lib/…
Lucas Nelson
3
Rails 5.0.0.1 config / environment / production.rb contiene config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?para que pueda configurar esto de manera diferente para su entorno sin cambiar el código que está registrado en su SCM.
tobinjim
Para habilitarlo: "exportar RAILS_SERVE_STATIC_FILES =" luego ejecuta "rails s -e production" Para deshabilitarlo: "unset RAILS_SERVE_STATIC_FILES"
Alfredo Osorio
32

En /config/environments/production.rbtuve que agregar esto:

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

El .js ya se estaba compilando previamente, pero lo agregué de todos modos. El .css y .css.erb aparentemente no ocurren automáticamente. No ^[^_]permite que los parciales se compilen: es una expresión regular.

Es un poco frustrante que los documentos indiquen claramente que la canalización de activos está habilitada de forma predeterminada, pero no aclara el hecho de que solo se aplica a los javascripts.

emersonthis
fuente
Necesita agregar styles.css a config.assets.precompile
Frederick Cheung
23

Pude resolver este problema cambiando: config.assets.compile = falsea
config.assets.compile = trueen/config/environments/production.rb

Actualización (24 de junio de 2018) : este método crea una vulnerabilidad de seguridad si la versión de Sprockets que está utilizando es inferior a 2.12.5, 3.7.2 o 4.0.0.beta8

Yanofsky
fuente
7
¿No significa esto que Rails está compilando los activos en lugar de, digamos, cargarlos desde un CDN?
Benjamin Oakes
@BenjaminOakes Sí, y eso es lo que quería
Yanofsky
2
Este modo utiliza más memoria, funciona peor que el predeterminado y no se recomienda. Es mejor usar un proxy nginx.
yekta
16

Para Rails 5, debe habilitar el siguiente código de configuración:

config.public_file_server.enabled = true

Por defecto, Rails 5 se envía con esta línea de configuración:

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

Por lo tanto, deberá establecer la variable de entorno RAILS_SERVE_STATIC_FILESen verdadero.

ytbryan
fuente
1
Para Rails 5, debo agregar, lo configuré passenger_env_var RAILS_SERVE_STATIC_FILES true;en el bloque de ubicación de mi aplicación en mi archivo nginx.conf.
Martin Velez
10

Hay 2 cosas que debe lograr para servir los activos en producción:

  1. Precompile los activos.
  2. Sirva los activos en el servidor al navegador.

1) Para precompilar los activos, tiene varias opciones.

  • Puede ejecutarlo rake assets:precompileen su máquina local, enviarlo al control de código fuente (git) y luego ejecutar el programa de implementación, por ejemplo, capistrano. Ésta no es una buena manera de comprometer activos precompilados en SCM.

  • Puede escribir una tarea de rake que se ejecute RAILS_ENV=production rake assets:precompileen los servidores de destino cada vez que implemente su aplicación Rails en producción, antes de reiniciar el servidor.

El código en una tarea para capistrano se verá similar a esto:

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) Ahora que tiene los activos en los servidores de producción, debe enviarlos al navegador.

Nuevamente, tiene varias opciones.

  • Active el servicio de archivos estáticos de Rails en config / environment / production.rb

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

    El uso de Rails para entregar archivos estáticos matará el rendimiento de la aplicación Rails.

  • Configure nginx (o Apache) para servir archivos estáticos.

    Por ejemplo, mi nginx que se configuró para funcionar con Puma se ve así:

    location ~ ^/(assets|images|fonts)/(.*)$ {
        alias /var/www/foster_care/current/public/$1/$2;
        gzip on;
        expires max;
        add_header Cache-Control public;
    }
Châu Hồng Lĩnh
fuente
4

Rails 4 ya no genera la versión sin huellas digitales del activo: no se generarán las hojas de estilo / style.css.

Si lo usa stylesheet_link_tag, se generará el enlace correcto a su hoja de estilo

Además styles.cssdebe estar en config.assets.precompilecuál está la lista de cosas que están precompiladas

Frederick Cheung
fuente
Veo el archivo de huellas digitales en el directorio / public / assets /. En mi diseño, tengo esto: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>¿Es esto incorrecto? ''
emersonthis
Por alguna razón, la implementación de producción todavía apunta a los archivos originales cuando veo la fuente. ¡ <link data-turbolinks-track="true" href="https://stackoverflow.com/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />Pero los archivos javascript son correctos! No entiendo por qué las mismas configuraciones funcionan para archivos .js pero no para .css.
emersonthis
On Rails 5.0.0.beta3 Recibo esta advertencia: ADVERTENCIA DE DEPRECATION: serve_static_filesestá en desuso y se eliminará en Rails 5.1. Utilice en su public_file_server.enabled = truelugar.
GMA
@emersonthis ¡Lo mismo! Js se carga perfectamente, pero algunos archivos CSS obtienen 404. ¿Resolviste esto?
IvRRimUm
Casi SIEMPRE es un problema con la configuración de la canalización de activos. Si tiene archivos en una ubicación que no es la predeterminada, ese es casi definitivamente el problema y debe informar a la canalización de activos al respecto utilizando algo como la primera respuesta.
emersonthis
3

cambiar su línea de archivo Production.rb

config.assets.compile = false

dentro

config.assets.compile = true

y también agregar

config.assets.precompile =  ['*.js', '*.css', '*.css.erb']
Jassa Mahal
fuente
¿Por qué compilar? se supone que no debemos compilar en producción mientras se ejecuta
James Tan
1
¡NUNCA HAGAS ESTO! Cualquiera que establezca config.assets.compile en verdadero en producción debería recibir un disparo.
bkunzi01
2

Estoy ejecutando Ubuntu Server 14.04 , Ruby 2.2.1 y Rails 4.2.4 He seguido un despliegue turorial de DigitalOcean y todo salió bien, pero cuando voy al navegador e ingreso la dirección IP de mi VPS mi aplicación está cargada pero sin estilos y javascript.

La aplicación se ejecuta con Unicorn y Nginx . Para solucionar este problema , ingresé a mi servidor usando SSH con mi usuario 'deployer' y fui a la ruta de mi aplicación, que es '/ home / deployer / apps / blog' y ejecuté el siguiente comando:

RAILS_ENV=production bin/rake assets:precompile

Luego reinicio el VPS y ¡listo! ¡Esto funciona para mi!

¡Espero que pueda ser útil para alguien más!

alexventuraio
fuente
2

Si la precompilación está configurada, NO necesita

config.assets.compile = true

ya que esto es para servir activos en vivo.

Nuestro problema fue que solo teníamos la base de claves secretas de desarrollo configuradas en config/secrets.yml

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Necesita entrada para el entorno de producción

xxjjnn
fuente
1
como se menciona en otras respuestas que necesita config.assets.precompile = ['*.js', '*.css', '*.css.erb'] y para ejecutarRAILS_ENV=production bundle exec rake assets:precompile
xxjjnn
1
esto permite la compilación de activos en vivo en producción, muy lento, no correcto
James Tan
2

Lo que NO DEBE hacer:

Algunos de mis colegas anteriores le han recomendado que haga esto:

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

La canalización de activos de rieles dice del enfoque anterior:

Este modo usa más memoria, funciona peor que el predeterminado y no se recomienda. Ver aquí: ( http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation )

Lo que DEBE hacer:

Precompile sus activos.

RAILS_ENV=production rake assets:precompile

Probablemente puedas hacer eso con una tarea de rastrillo.

BKSpurgeon
fuente
Sin embargo, ¿por qué agregar artefactos de compilación al git? Simplemente puede agregar la tarea de rake a su proceso de compilación y evitar gitspam masivo (especialmente si tiene uglifier y gzipping, que debería)
Dr.Strangelove
@ Dr.Strangelove Gracias por su comentario - no sé lo suficiente sobre eso -: ¿pueden elaborar / editar la publicación original?
BKSpurgeon
1

El comparador predeterminado para compilar archivos incluye application.js, application.css y todos los archivos que no son JS / CSS (esto incluirá todos los activos de imagen automáticamente) de las carpetas de aplicaciones / activos, incluidas sus gemas:

Si tiene otros manifiestos u hojas de estilo individuales y archivos JavaScript para incluir, puede agregarlos a la matriz de precompilación en 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
fuente
1

En primer lugar, verifique sus activos, es posible que haya algún error en la compilación previa de los activos.

Para precompilar activos en producción ENV, ejecute este comando:

RAILS_ENV=production rake assets:precompile

Si muestra un error, elimínelo primero,

En caso de error de "variable indefinida", cargue ese archivo de variable antes de usarlo en otro archivo.

ejemplo:

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

en el archivo application.rb, secuencia de precompilación de activos

ejemplo:

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']
Chitresh goyal
fuente
1

Encontró esto:

Se config.serve_static_assetsha cambiado el nombre de la opción de configuración a config.serve_static_filespara aclarar su función.

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

Así que configure env RAILS_SERVE_STATIC_FILESo use Nginxpara servir archivos estáticos. Agregar config.serve_static_assets = trueseguirá funcionando, pero se eliminará en el futuro.

Daniel Wei
fuente
1

No se recomienda dejar que capistrano realice la precompilación de activos, ya que puede llevar años y, a menudo, un tiempo de espera. intente hacer precompilación de activos locales.

Primero, configure en config / application.rb config.assets.initialize_on_precompile = false luego haga local RAILS_ENV=production bin/rake assets:precompile y agregue esos activos públicos a git.

y config / environment / development.rb, cambie la ruta de sus activos para evitar el uso de activos precompilados:

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

Si tiene un problema de conexión con la base de datos, significa que tiene un inicializador que utiliza la base de datos. una forma de evitarlo es establecer un nuevo entorno duplicando production.rb como quizás production2 .rb, y en database.yml, agregar el entorno de producción2 con la configuración de db de desarrollo . entonces hazlo

RAILS_ENV=production2 bin/rake assets:precompile

si todavía tiene algún problema con los activos, por ejemplo, ckeditor, agregue el archivo js en config / initializers / assets.rb

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

James Tan
fuente
0

Puede que me equivoque, pero los que recomiendan cambiar

config.assets.compile = true

El comentario en esta línea dice: #No recurra a la canalización de activos si se pierde un activo precompilado.

Esto sugiere que al establecer esto en verdadero, no está solucionando el problema, sino más bien evitándolo y ejecutando la canalización cada vez. ¿Esto seguramente debe matar su desempeño y frustrar el propósito de la tubería?

Tuve este mismo error y se debió a que la aplicación se estaba ejecutando en una subcarpeta que Rails no conocía.

Entonces mi archivo css estaba en casa / subcarpeta / aplicación / público / .... pero rails estaba buscando en casa / aplicación / público / ...

intente sacar su aplicación de la subcarpeta o decirle a Rails que está en una subcarpeta.

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

Esto me solucionó el problema en producción. Ponlo en la configuración de nginx.

Pedro Adame Vergara
fuente
0

Incluso nos enfrentamos al mismo problema donde RAILS_ENV=production bundle exec rake assets:precompiletuvimos éxito, pero las cosas no funcionaron como se esperaba.
Descubrimos que el unicornio era el principal culpable aquí.

Igual que en su caso, incluso solíamos reiniciar unicorn después de compilar los activos. Se notó que cuando se reinicia unicorn, solo se reinician sus procesos de trabajo y no el proceso maestro.
Esta es la razón principal por la que no se sirven los activos correctos.

Más tarde, después de compilar los activos, paramos e iniciamos unicorn para que el proceso maestro de unicornio también se reinicie y se sirvan los activos correctos.
Detener e iniciar el unicornio trae alrededor de 10 segundos de tiempo de inactividad en comparación con reiniciar el unicornio. Esta es la solución alternativa que se puede utilizar cuando, como solución a largo plazo, se pasa de unicornio a puma.

Bhavya Keniya
fuente