Trilhos 4: ativos não carregados na produção

116

Estou tentando colocar meu aplicativo em produção e os caminhos de recursos de imagem e css não estão funcionando.

Aqui está o que estou fazendo atualmente:

  • Ativos de imagem em /app/assets/images/image.jpg
  • As folhas de estilo estão em /app/assets/stylesheets/style.css
  • Em meu layout, faço referência ao arquivo css desta forma: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
  • Antes de reiniciar o unicórnio, eu corro RAILS_ENV=production bundle exec rake assets:precompilee ele consegue e vejo os arquivos de impressão digital no public/assetsdiretório.

Quando eu navego em meu site, recebo um erro 404 não encontrado para mysite.com/stylesheets/styles.css.

O que estou fazendo de errado?

Atualização: no meu layout, é assim:

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

A fonte de geração é 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 o Rails não está procurando apropriadamente pelos arquivos css compilados. Mas é muito confuso porque está funcionando corretamente para javascripts (observe o /assets/****.jscaminho).

emerso
fonte
Você pode nos dizer como carrega seu arquivo css? Pelo seu erro, parece que você tenta fazer um hardlink em vez de usar stylesheet_link_tag.
kik
1
Apenas adicionado acima. Estou fazendo<%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" => true %>
finalização em
Ok, então eu recomendaria duas coisas: 1. verifique na fonte gerada se esta linha está escrita como caminho para public/assetse 2. verifique se não há outra instrução em algum lugar tentando carregar aquele arquivo css (presumivelmente codificado)
kik
Não posso dizer se usar .erb é um problema porque eu nunca faço isso: .home {background: #FFF url(<%= image_path 'hippopotamus.jpg' %>) no-repeat; }pode realmente ser substituído na roda dentada por .home {background: #FFF url(image-path('hippopotamus.jpg')) no-repeat; }. Talvez você possa tentar se isso ajudar.
kik
Você está dizendo que posso tornar essa referência dinâmica em meu arquivo css sem adicionar a extensão .erb? Eu mudei porque não queria que o link quebrasse quando estou no modo de desenvolvimento.
início em

Respostas:

105

No trilho 4, você precisa fazer as alterações abaixo:

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

Isso funciona comigo. use o seguinte comando para pré-compilar recursos

RAILS_ENV=production bundle exec rake assets:precompile

Boa sorte!

Rameshwar Vyevhare
fonte
11
Achei que definir config.assets.compile como true prejudicaria o desempenho na produção. também, css.erb? quem usa isso? e que tal ousadia e café?
ahnbizcad
quando os arquivos coffee e sass são solicitados, eles são processados ​​pelos processadores fornecidos pelas gemas coffee-script e sass-rails e, em seguida, enviados de volta ao navegador como JavaScript e CSS, respectivamente.
Rameshwar Vyevhare 01 de
1
Este problema já foi resolvido para Rails 4 e, portanto, não há necessidade de usar turbo-sprocket-rails3 gem
Rameshwar Vyevhare 01/09/2014
4
Desculpe, não estou conseguindo fazer a conexão do que você disse para responder à minha pergunta.
ahnbizcad 01 de
1
Normalmente, quando você executa o servidor de produção, você executa o Rails com passageiro ou unicórnio ou puma por trás do servidor Apache ou nginx. É melhor deixar Apache ou nginx servir arquivos estáticos (js, css, imagens), e o servidor de aplicação Rails (puma, unicórnio) servir código Rails e template. Para fazer isso, você deve desligar config.serve_static_filese configurar o alias no Apache e nginx para lidar com ele assets.
Châu Hồng Lĩnh
85

Acabei de ter o mesmo problema e encontrei esta configuração em config / environment / production.rb:

# Rails 4:
config.serve_static_assets = false

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

Mudar para fazê- truelo funcionar. Parece que por padrão o Rails espera que você tenha configurado seu servidor web front-end para lidar com solicitações de arquivos fora da pasta pública ao invés de procurá-los para o aplicativo Rails. Talvez você tenha feito isso para seus arquivos javascript, mas não para suas folhas de estilo CSS?

( Veja a documentação do Rails 5 ). Como notado nos comentários, com Rails 5 você pode apenas definir a RAILS_SERVE_STATIC_FILESvariável de ambiente, já que a configuração padrão é config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?.

Davmac
fonte
1
AVISO DE DEPRECAÇÃO: A opção de configuração config.serve_static_assetsfoi renomeada para config.serve_static_filesesclarecer sua função (ela apenas permite servir tudo na publicpasta e não está relacionada ao pipeline de ativos). O serve_static_assetsalias será removido no Rails 5.0. Migre seus arquivos de configuração de acordo.
yekta 01 de
Antes, quando eu estava enfrentando esse problema, mudar essa linha tinha resolvido para mim, mas agora estou enfrentando de novo (não sei como continuo terminando nessas situações) e isso não é suficiente. Mais alguma sugestão sobre o que pode estar errado?
IIllIIll
2
Esta deve ser a resposta aceita. Embora esteja config.serve_static_filesno Rails 4.2 e config.public_file_server.enabledno 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 contém config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?para que você possa definir isso de forma diferente para o seu ambiente, sem alterar o código que é verificado em seu SCM.
tobinjim de
Para habilitá-lo: "export RAILS_SERVE_STATIC_FILES =" então você executa "rails s -e production" Para desabilitá-lo: "unset RAILS_SERVE_STATIC_FILES"
Alfredo Osorio
32

Em /config/environments/production.rbeu tive que adicionar isto:

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

O .js já estava sendo pré-compilado, mas eu o adicionei mesmo assim. Aparentemente, .css e .css.erb não acontecem automaticamente. O ^[^_]exclui parciais de serem compilados - é um regexp.

É um pouco frustrante que os documentos afirmem claramente que o pipeline de ativos ESTÁ habilitado por padrão, mas não esclarece o fato de que se aplica apenas a javascripts.

emerso
fonte
Você precisa adicionar styles.css a config.assets.precompile
Frederick Cheung
23

Consegui resolver este problema mudando: config.assets.compile = falsepara
config.assets.compile = trueem/config/environments/production.rb

Atualização (24 de junho de 2018) : este método cria uma vulnerabilidade de segurança se a versão do Sprockets que você está usando for inferior a 2.12.5, 3.7.2 ou 4.0.0.beta8

Yanofsky
fonte
7
Isso não significa que o Rails está compilando os ativos em vez de, digamos, carregá-los de um CDN?
Benjamin Oakes
@BenjaminOakes Sim, e era isso que eu queria
Yanofsky
2
Este modo usa mais memória, tem um desempenho inferior ao padrão e não é recomendado. Melhor usar um proxy nginx.
yekta 01 de
16

Para Rails 5, você deve habilitar o seguinte código de configuração:

config.public_file_server.enabled = true

Por padrão, o Rails 5 vem com esta linha de configuração:

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

Portanto, você precisará definir a variável de ambiente RAILS_SERVE_STATIC_FILEScomo true.

ytbryan
fonte
1
Para Rails 5, devo acrescentar, eu defini passenger_env_var RAILS_SERVE_STATIC_FILES true;no bloco de localização do meu aplicativo em meu arquivo nginx.conf.
Martin Velez
10

Existem 2 coisas que você deve realizar para atender aos ativos em produção:

  1. Pré-compilar os ativos.
  2. Sirva os ativos do servidor para o navegador.

1) Para pré-compilar os ativos, você tem várias opções.

  • Você pode executar rake assets:precompileem sua máquina local, confirmá-lo no controle de código-fonte (git) e, em seguida, executar o programa de implantação, por exemplo, capistrano. Essa não é uma boa maneira de comprometer ativos pré-compilados ao SCM.

  • Você pode escrever uma tarefa rake que é executada RAILS_ENV=production rake assets:precompilenos servidores de destino cada vez que você implanta seu aplicativo Rails para produção, antes de reiniciar o servidor.

O código em uma tarefa para capistrano será semelhante a este:

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) Agora, você tem os ativos nos servidores de produção e precisa veiculá-los no navegador.

Novamente, você tem várias opções.

  • Ative o arquivo estático do Rails servindo em config / environment / production.rb

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

    Usar Rails para servir arquivos estáticos vai matar o desempenho de seu aplicativo Rails.

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

    Por exemplo, meu nginx que foi configurado para funcionar com Puma se parece com isto:

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

O Rails 4 não gera mais a versão sem impressão digital do ativo: stylesheets / style.css não serão gerados para você.

Se você usar stylesheet_link_tag, o link correto para sua folha de estilo será gerado

Além disso, styles.cssdeve estar em config.assets.precompilequal está a lista de coisas que são pré-compiladas

Frederick Cheung
fonte
Vejo o arquivo com impressão digital no diretório / public / assets /. Em meu layout, tenho o seguinte: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>Isso está incorreto? `
emerso em
Por algum motivo, a implantação de produção ainda está apontando para os arquivos originais quando eu visualizo o código-fonte. <link data-turbolinks-track="true" href="https://stackoverflow.com/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />Mas os arquivos javascript estão corretos! Não entendo por que as mesmas configurações funcionam para arquivos .js, mas não para .css.
início em
No Rails 5.0.0.beta3 eu recebo este aviso: AVISO DE DEPRECAÇÃO: serve_static_filesestá obsoleto e será removido no Rails 5.1. Em public_file_server.enabled = truevez disso, use .
GMA
@emersonthis Same! Js carrega perfeitamente, mas alguns arquivos css ficam 404. Você resolveu isso?
IvRRimUm
É quase SEMPRE um problema com a configuração do pipeline de ativos. Se você tiver arquivos em qualquer local que não seja o padrão, esse é quase definitivamente o problema e você precisa informar o pipeline de ativos sobre isso usando algo como a primeira resposta.
emersonthis
3

mude sua linha de arquivo Production.rb

config.assets.compile = false

para dentro

config.assets.compile = true

e também adicionar

config.assets.precompile =  ['*.js', '*.css', '*.css.erb']
Jassa Mahal
fonte
por que compilar? não devemos compilar em produção durante sua execução
James Tan
1
NUNCA FAÇA ISSO! Qualquer pessoa que definir config.assets.compile como true na produção deve ser morta.
bkunzi01
2

Estou executando o Ubuntu Server 14.04 , Ruby 2.2.1 e Rails 4.2.4 Eu segui um turorial de implantação da DigitalOcean e tudo correu bem, mas quando vou ao navegador e o endereço IP do meu VPS meu aplicativo é carregado, mas sem estilos e javascript.

O aplicativo está sendo executado com Unicorn e Nginx . Para corrigir esse problema, entrei em meu servidor usando SSH com meu usuário 'deployer' e acessei o caminho do meu aplicativo que é '/ home / deployer / apps / blog' e execute o seguinte comando:

RAILS_ENV=production bin/rake assets:precompile

Depois é só reiniciar o VPS e pronto! Funciona para mim!

Espero que possa ser útil para outra pessoa!

alexventuraio
fonte
2

Se a pré-compilação estiver definida, você NÃO precisa

config.assets.compile = true

pois isso é para servir ativos ao vivo.

Nosso problema era que só tínhamos a base da chave secreta de desenvolvimento definida em config/secrets.yml

development:
    secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'

Precisa de entrada para ambiente de produção

xxjjnn
fonte
1
conforme mencionado em outras respostas que você precisa config.assets.precompile = ['*.js', '*.css', '*.css.erb'] e para executarRAILS_ENV=production bundle exec rake assets:precompile
xxjjnn
1
isso permite a compilação de recursos durante a produção ao vivo, muito lento, incorreto
James Tan
2

O que você NÃO DEVE fazer:

Alguns dos meus colegas acima recomendaram que você fizesse isso:

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

O pipeline de ativos do Rails diz sobre a abordagem acima:

Este modo usa mais memória, tem um desempenho inferior ao padrão e não é recomendado. Veja aqui: ( http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation )

O que você deveria fazer:

Pré-compile seus ativos.

RAILS_ENV=production rake assets:precompile

Você provavelmente pode fazer isso com uma tarefa de rake.

BKSpurgeon
fonte
Por que adicionar artefatos de construção ao git? Você pode simplesmente adicionar a tarefa rake ao seu processo de construção e evitar gitspam massivo (especialmente se você tiver uglifier e gzipping ativado, o que você deve)
Dr.Strangelove
@ Dr.Strangelove Obrigado pelo seu comentário - não sei o suficiente sobre isso -: você pode elaborar / editar a postagem original?
BKSpurgeon
1

O matcher padrão para compilar arquivos inclui application.js, application.css e todos os arquivos não JS / CSS (isso incluirá todos os ativos de imagem automaticamente) das pastas app / assets incluindo suas joias:

Se você tiver outros manifestos ou folhas de estilo individuais e arquivos JavaScript para incluir, poderá adicioná-los à matriz de pré-compilação em 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
fonte
1

Em primeiro lugar, verifique seus ativos, pode ser possível que haja algum erro na pré-compilação de ativos.

Para pré-compilar ativos em produção ENV execute este comando:

RAILS_ENV=production rake assets:precompile

Se mostrar erro, remova-o primeiro,

Em caso de erro de "variável indefinida", carregue esse arquivo de variável antes de usá-lo em outro arquivo.

exemplo:

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

no arquivo application.rb conjunto de sequência de pré-compilação de ativos

exemplo:

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

Encontrei isto:

A opção de configuração config.serve_static_assetsfoi renomeada config.serve_static_filespara esclarecer sua função.

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

Portanto, defina env RAILS_SERVE_STATIC_FILESou using Nginxpara servir arquivos estáticos. Adicionar config.serve_static_assets = trueainda funcionará, mas será removido no futuro.

Daniel Wei
fonte
1

não é recomendado deixar o capistrano fazer a pré-compilação dos ativos, porque pode levar anos e muitas vezes expirar. tente fazer a pré-compilação dos ativos locais.

Primeiro, defina em config / application.rb config.assets.initialize_on_precompile = false e faça local RAILS_ENV=production bin/rake assets:precompile e adicione esses public / assets ao git.

e config / environment / development.rb, altere o caminho do seu ativo para evitar o uso de ativos pré-compilados:

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

Se você tiver problema de conexão db, significa que você tem um inicializador que usa db. uma maneira de contornar isso é definir um novo ambiente duplicando production.rb como, talvez, production2 .rb, e em database.yml, adicionar o ambiente production2 com configuração de banco de dados de desenvolvimento . então faça

RAILS_ENV=production2 bin/rake assets:precompile

se você ainda está enfrentando algum problema com ativos, por exemplo ckeditor, adicione o arquivo js em config / initializers / assets.rb

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

James Tan
fonte
0

Posso estar errado, mas aqueles que recomendam mudar

config.assets.compile = true

O comentário nesta linha diz: # Não faça fallback para o pipeline de recursos se um recurso pré-compilado for perdido.

Isso sugere que, ao definir isso como true, você não está corrigindo o problema, mas sim ignorando-o e executando o pipeline todas as vezes. Isso certamente deve matar seu desempenho e anular o propósito do pipeline?

Eu tive esse mesmo erro e foi devido ao aplicativo rodando em uma subpasta que o rails não conhecia.

Portanto, meu arquivo css estava em home / subfolder / app / public / .... mas rails estava em home / app / public / ...

tente mover seu aplicativo para fora da subpasta ou dizer ao Rails que ele está em uma subpasta.

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

Isso resolveu o meu problema na produção. Coloque-o na configuração do nginx.

Pedro Adame Vergara
fonte
0

Mesmo nós enfrentamos o mesmo problema onde RAILS_ENV=production bundle exec rake assets:precompiletivemos sucesso, mas as coisas não funcionaram como esperado.
Descobrimos que o unicórnio era o principal culpado aqui.

Como no seu caso, mesmo nós costumávamos reiniciar o Unicórnio após compilar os ativos. Percebeu-se que quando o unicórnio é reiniciado, apenas seus processos de trabalho são reiniciados e não o processo mestre.
Este é o principal motivo pelo qual os ativos corretos não são veiculados.

Mais tarde, após compilar os ativos, paramos e iniciamos o unicórnio para que o processo mestre do unicórnio também seja reiniciado e os ativos corretos sejam entregues.
Parar e iniciar o unicórnio traz cerca de 10 segundos de tempo de inatividade em comparação com reiniciá-lo. Esta é a solução alternativa que pode ser usada quando a solução de longo prazo é mudar de unicórnio para puma.

Bhavya Keniya
fonte