65

I have spent the better part of the day trying to get images to load on my heroku app. Everything I try works locally, but not after being deployed to heroku.

I have png files saved in the images folder under my assets. I am referencing these images with syntax in my css such as;

#signin {
  background: url(<%= asset_path 'sf.png' %>);
  background-size: 100%;
}

In heroku when I inspect the background the assets/sf.png link is there but when you click it it shows a broken image, suggesting it did not load properly.

I've tried toggling config.serve_static_assets = false in the production.rb file between true and false and neither works.

I also have

group :production do
  gem 'pg'
  gem 'rails_12factor'
end

Precompile is always successful.

Rails 4. Any ideas on what else to try?

Igor Ivancha
  • 3,413
  • 4
  • 30
  • 39
brad
  • 1,675
  • 2
  • 16
  • 23

9 Answers9

92

I needed to combine several solutions to make this work, here is what I did:

Gemfile

gem 'rails_12factor', group: :production

in my Heroku console

heroku labs:enable user-env-compile -a yourapp

production.rb

config.serve_static_assets = true
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
config.assets.compile = true

I didn't need to precompile the assets locally.

davegson
  • 8,205
  • 4
  • 51
  • 71
kal
  • 929
  • 1
  • 5
  • 4
  • 23
    I already had the gem, but other than that, `config.assets.compile = true` sufficed for me. Running Ruby 2.0, Rails 4.0, on EU Cedar stack. – zykadelic Nov 26 '13 at 10:03
  • 1
    This is dirty fix since you will have runtime compiling due to `config.assets.compile = true`. It will work but it is not proper production setup. – Haris Krajina May 06 '14 at 07:00
  • 6
    No such feature: user-env-compile – Nadeem Yasin May 28 '14 at 05:58
  • 2
    Don't compile assets true on production. that makes production slow. Instead create `config/initializers/assets.rb`, and add these to it, so that rails production recognizes vendor and lib precompiled assets. `Rails.application.config.assets.precompile << /\.(?:png|jpg|jpeg|gif)\z/` `Rails.application.config.assets.precompile << /\.(?:svg|eot|woff|ttf)\z/` – ahnbizcad Nov 07 '14 at 09:55
  • 3
    @gwho, this doesn't seem to work for me. putting `config.assets.precompile += %w( .svg .eot .woff .ttf .png .jpg .gif)` in '/config/application.rb' helped me. will this solution slow down the production? – Evgenia Karunus Dec 29 '14 at 07:43
  • @lakesare interesting. it shouldn't slow it down. My solution is roughly the same as yours, except the `Rails.application.` is already called in the application.rb I will have to look into it. But the answer to your question should be a "no", since the intent is the same, and they both avoid live compilation. – ahnbizcad Jan 02 '15 at 21:34
  • Depracation warning from rails: The configuration option `config.serve_static_assets` has been renamed to `config.serve_static_files` to clarify its role (it merely enables serving everything in the `public` folder and is unrelated to the asset pipeline). The `serve_static_assets` alias will be removed in Rails 5.0. Please migrate your configuration files accordingly. – Benjamin Linville Feb 08 '16 at 15:20
  • I attempted to implement the above answer on Rails 5.0.1 and it broke the application completely upon pushing to Heroku. Just a heads up. –  Mar 28 '17 at 13:06
  • I'm trying the solution from @ahnbizcad. It doesn't seem to affect anything. Setting assets.compile to true is working for me, but if that affects performance speed, I would really like to find a better solution. Is there possibly something else I need to do? He mentioned that Rails.application is already called in application.rb. I'm not sure how to tell whether my app is already doing that. – Jeff Zivkovic Aug 24 '18 at 13:37
  • I also tried the solution from @lakesare. No luck. – Jeff Zivkovic Aug 24 '18 at 13:37
  • i suspect version drift – ahnbizcad Aug 28 '18 at 19:42
57

You need to do two things to resolve it. First, change these two lines from false to true in production.rb file.

      config.assets.compile = true
      config.assets.digest = true

Second, if you've syntax like this for your images

    background: url("imgo.jpg") 

Change it to

     background: image-url("image.jpg")

I hope it does your job.

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
Prabhakar
  • 6,458
  • 2
  • 40
  • 51
  • 4
    Yes!!! Nothing else worked for me but this did (setting `config.assets.compile` to `true`). – Jason Swett Jul 27 '15 at 12:43
  • Yes this worked for me too! Thanks! Configuring: config.assets.compile = true – BV45 Mar 21 '16 at 18:38
  • Not sure why this isn't top comment. None of the other answers worked for me. You just saved me from wasting hours on this. I didn't need to mess with anything else except assets.compile. – Jubl Jun 02 '16 at 19:00
  • 1
    40 posts later, you finally answered my question. Thank you! – Luminusss Jun 06 '16 at 22:47
  • When I set config.assets.compile = false, I can see my app without loading any of the css, image, and ... files (They're not accessible). When I change it to true, I cannot see my website, but all files are accessible via their own link!! Do you have any idea to solve it? – Aboozar Rajabi Jun 14 '16 at 23:53
  • Setting config.assets.compile = true will tremendously slow your app down and consume much more memory. If you notice your pages rendering much slower in production, this is why! – bkunzi01 Sep 08 '16 at 21:50
27

Another issue, I was having with this was that I was precompiling my assets locally, prior to loading it to heroku. This requires you to follow a different set of steps, which can be found below. If you precompile your assets locally, you must follow these steps or any updates you made to your assets folder will not be reflected in prod.

https://devcenter.heroku.com/articles/rails-asset-pipeline

RAILS_ENV=production bundle exec rake assets:precompile

commit and push to server.

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
brad
  • 1,675
  • 2
  • 16
  • 23
13

I had a similar issue and I solved it with the following line in the custom.css.scss.. Tell me if this works for you.

background: image-url('sf.png')

Referencing the asset being done different ways depending if you are using ERB or Sass, see in the Ruby on Rails Guide.

Percevalve
  • 131
  • 1
  • 2
3

I don't have the reputation to comment (yet) but it's important to note that the Heroku labs feature has been removed, so now you'll get a "No such feature: user-env-compile" error

More: https://github.com/Crowdtilt/CrowdtiltOpen/issues/251

alightholder
  • 115
  • 8
2

Rails ('4.1.5') I had a similar issue of images not showing on Heroku but showing up locally. I am not using paperclip or carrierwave gems, I precompile locally and also using RAILS_ENV=production I push to github and it deploys fine to Heroku.

I solved the issue by having:

config.serve_static_assets = true
config.assets.compile = true
config.assets.js_compressor = :uglifier
config.assets.digest = true

// delete precompiled assets
bundle exec rake assets:clobber --trace
RAIL_ENV=production bundle exec rake assets:clobber --trace

copied images to public/assets from app/assets. then:

// tests should pass
bundle exec rake assets:precompile --trace
RAILS_ENV=production bundle exec rake assets:precompile --trace

git commit
git push

And it was running fine on Heroku.

Batz
  • 342
  • 1
  • 5
  • 15
1

I had a similar problem with showing just images. Being new to rails I did not know I could use:

<%= image_tag("fileName.png", alt: "File Name Fancy", size: "100x100")%>

Instead of traditional html.

The image_tag is explained in the rails api but I find its use is better explained here: http://apidock.com/rails/ActionView/Helpers/AssetTagHelper/image_tag

All I added to my app was this gem: gem 'rails_12factor', group: :production

As described in the heroku asset-pipeline documentation. https://devcenter.heroku.com/articles/rails-4-asset-pipeline

Jorge Diaz
  • 101
  • 1
  • 3
1

I tried many solutions too but i found an invaluable solution and explanation 1. Heroku looks for assets in the public folder and that means you have to pre-compile your assets but if you were like me someone looking for a way to precompile my assets when my development environment is set to gem sqlite and production set to pg then you would do this.

in your production.rb

config.serve_static_assets = true

if you do not have gem pg installed you need to comment it out and change your production environment to use gem sqlite and run this

RAILS_ENV=production bundle exec rake assets:precompile

when all assets have been precompiled, switch back to your default settings and git add .,commit, and push to heroku

user2903934
  • 59
  • 1
  • 11
-1

The images won't be served as assets by default, only css and js. You should look into the answer of

Syed Ehtsham Abbas in this question Heroku does NOT compile files under assets pipelines in Rails 4

Community
  • 1
  • 1
Dzung Nguyen
  • 9,152
  • 14
  • 65
  • 104